LCOV - code coverage report
Current view: top level - vcl/source/gdi - bitmap2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 333 581 57.3 %
Date: 2012-08-25 Functions: 18 19 94.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 277 769 36.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <tools/zcodec.hxx>
      31                 :            : #include <tools/stream.hxx>
      32                 :            : #include <vcl/salbtype.hxx>
      33                 :            : #include <vcl/bmpacc.hxx>
      34                 :            : #include <vcl/outdev.hxx>
      35                 :            : #include <vcl/bitmap.hxx>
      36                 :            : 
      37                 :            : #include <utility>
      38                 :            : 
      39                 :            : #if defined(HAVE_MEMCHECK_H)
      40                 :            : #include <memcheck.h>
      41                 :            : #endif
      42                 :            : 
      43                 :            : 
      44                 :            : // -----------
      45                 :            : // - Defines -
      46                 :            : // -----------
      47                 :            : 
      48                 :            : #define DIBCOREHEADERSIZE           ( 12UL )
      49                 :            : #define DIBINFOHEADERSIZE           ( sizeof( DIBInfoHeader ) )
      50                 :            : #define BITMAPINFOHEADER                        0x28
      51                 :            : 
      52                 :            : // ----------------------
      53                 :            : // - Compression defines
      54                 :            : // ----------------------
      55                 :            : 
      56                 :            : #define COMPRESS_OWN                ('S'|('D'<<8UL))
      57                 :            : #define COMPRESS_NONE               ( 0UL )
      58                 :            : #define RLE_8                       ( 1UL )
      59                 :            : #define RLE_4                       ( 2UL )
      60                 :            : #define BITFIELDS                   ( 3UL )
      61                 :            : #define ZCOMPRESS                   ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */
      62                 :            : 
      63                 :            : // -----------------
      64                 :            : // - DIBInfoHeader -
      65                 :            : // -----------------
      66                 :            : 
      67                 :            : struct DIBInfoHeader
      68                 :            : {
      69                 :            :     sal_uInt32      nSize;
      70                 :            :     sal_Int32       nWidth;
      71                 :            :     sal_Int32       nHeight;
      72                 :            :     sal_uInt16      nPlanes;
      73                 :            :     sal_uInt16      nBitCount;
      74                 :            :     sal_uInt32      nCompression;
      75                 :            :     sal_uInt32      nSizeImage;
      76                 :            :     sal_Int32       nXPelsPerMeter;
      77                 :            :     sal_Int32       nYPelsPerMeter;
      78                 :            :     sal_uInt32      nColsUsed;
      79                 :            :     sal_uInt32      nColsImportant;
      80                 :            : 
      81                 :        197 :                     DIBInfoHeader() :
      82                 :            :                         nSize( 0UL ),
      83                 :            :                         nWidth( 0UL ),
      84                 :            :                         nHeight( 0UL ),
      85                 :            :                         nPlanes( 0 ),
      86                 :            :                         nBitCount( 0 ),
      87                 :            :                         nCompression( 0 ),
      88                 :            :                         nSizeImage( 0 ),
      89                 :            :                         nXPelsPerMeter( 0UL ),
      90                 :            :                         nYPelsPerMeter( 0UL ),
      91                 :            :                         nColsUsed( 0UL ),
      92                 :        197 :                         nColsImportant( 0UL ) {}
      93                 :            : 
      94                 :        197 :                     ~DIBInfoHeader() {}
      95                 :            : };
      96                 :            : 
      97                 :            : namespace
      98                 :            : {
      99                 :        109 :     inline sal_uInt16 discretizeBitcount( sal_uInt16 nInputCount )
     100                 :            :     {
     101                 :            :         return ( nInputCount <= 1 ) ? 1 :
     102                 :            :                ( nInputCount <= 4 ) ? 4 :
     103 [ +  + ][ +  + ]:        109 :                ( nInputCount <= 8 ) ? 8 : 24;
                 [ +  + ]
     104                 :            :     }
     105                 :            : 
     106                 :         51 :     inline bool isBitfieldCompression( sal_uLong nScanlineFormat )
     107                 :            :     {
     108                 :            :         return nScanlineFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ||
     109 [ +  - ][ -  + ]:         51 :             nScanlineFormat == BMP_FORMAT_32BIT_TC_MASK;
     110                 :            :     }
     111                 :            : }
     112                 :            : 
     113                 :            : // ----------
     114                 :            : // - Bitmap -
     115                 :            : // ----------
     116                 :            : 
     117                 :       6939 : SvStream& operator>>( SvStream& rIStm, Bitmap& rBitmap )
     118                 :            : {
     119                 :       6939 :     rBitmap.Read( rIStm, sal_True );
     120                 :       6939 :     return rIStm;
     121                 :            : }
     122                 :            : 
     123                 :            : // ------------------------------------------------------------------
     124                 :            : 
     125                 :          0 : SvStream& operator<<( SvStream& rOStm, const Bitmap& rBitmap )
     126                 :            : {
     127                 :          0 :     rBitmap.Write( rOStm, sal_False, sal_True );
     128                 :          0 :     return rOStm;
     129                 :            : }
     130                 :            : 
     131                 :            : // ------------------------------------------------------------------
     132                 :            : 
     133                 :       7064 : sal_Bool Bitmap::Read( SvStream& rIStm, sal_Bool bFileHeader, sal_Bool bIsMSOFormat )
     134                 :            : {
     135                 :       7064 :     const sal_uInt16    nOldFormat = rIStm.GetNumberFormatInt();
     136                 :       7064 :     const sal_uLong     nOldPos = rIStm.Tell();
     137                 :       7064 :     sal_uLong           nOffset = 0UL;
     138                 :       7064 :     sal_Bool            bRet = sal_False;
     139                 :            : 
     140         [ +  - ]:       7064 :     rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     141                 :            : 
     142         [ +  - ]:       7064 :     if( bFileHeader )
     143                 :            :     {
     144 [ +  - ][ +  + ]:       7064 :         if( ImplReadDIBFileHeader( rIStm, nOffset ) )
     145         [ +  - ]:        159 :             bRet = ImplReadDIB( rIStm, *this, nOffset );
     146                 :            :     }
     147                 :            :     else
     148         [ #  # ]:          0 :         bRet = ImplReadDIB( rIStm, *this, nOffset, bIsMSOFormat );
     149                 :            : 
     150         [ +  + ]:       7064 :     if( !bRet )
     151                 :            :     {
     152         [ +  + ]:       7018 :         if( !rIStm.GetError() )
     153         [ +  - ]:        113 :             rIStm.SetError( SVSTREAM_GENERALERROR );
     154                 :            : 
     155         [ +  - ]:       7018 :         rIStm.Seek( nOldPos );
     156                 :            :     }
     157                 :            : 
     158         [ +  - ]:       7064 :     rIStm.SetNumberFormatInt( nOldFormat );
     159                 :            : 
     160                 :       7064 :     return bRet;
     161                 :            : }
     162                 :            : 
     163                 :            : // ------------------------------------------------------------------
     164                 :            : 
     165                 :        159 : sal_Bool Bitmap::ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, sal_uLong nOffset, sal_Bool bIsMSOFormat )
     166                 :            : {
     167                 :        159 :     DIBInfoHeader   aHeader;
     168                 :        159 :     const sal_uLong     nStmPos = rIStm.Tell();
     169                 :        159 :     sal_Bool            bRet = sal_False;
     170                 :        159 :     sal_Bool        bTopDown = sal_False;
     171                 :            : 
     172 [ +  + ][ +  - ]:        159 :     if( ImplReadDIBInfoHeader( rIStm, aHeader, bTopDown, bIsMSOFormat ) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount )
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
     173                 :            :     {
     174                 :         46 :         const sal_uInt16 nBitCount( discretizeBitcount(aHeader.nBitCount) );
     175                 :            : 
     176                 :         46 :         const Size          aSizePixel( aHeader.nWidth, abs(aHeader.nHeight) );
     177                 :         46 :         BitmapPalette       aDummyPal;
     178         [ +  - ]:         46 :         Bitmap              aNewBmp( aSizePixel, nBitCount, &aDummyPal );
     179         [ +  - ]:         46 :         BitmapWriteAccess*  pAcc = aNewBmp.AcquireWriteAccess();
     180                 :            : 
     181         [ +  - ]:         46 :         if( pAcc )
     182                 :            :         {
     183                 :            :             sal_uInt16          nColors;
     184                 :            :             SvStream*       pIStm;
     185                 :         46 :             SvMemoryStream* pMemStm = NULL;
     186                 :         46 :             sal_uInt8*          pData = NULL;
     187                 :            : 
     188         [ +  + ]:         46 :             if( nBitCount <= 8 )
     189                 :            :             {
     190         [ +  - ]:         27 :                 if( aHeader.nColsUsed )
     191                 :         27 :                     nColors = (sal_uInt16) aHeader.nColsUsed;
     192                 :            :                 else
     193                 :          0 :                     nColors = ( 1 << aHeader.nBitCount );
     194                 :            :             }
     195                 :            :             else
     196                 :         19 :                 nColors = 0;
     197                 :            : 
     198         [ -  + ]:         46 :             if( ZCOMPRESS == aHeader.nCompression )
     199                 :            :             {
     200         [ #  # ]:          0 :                 ZCodec  aCodec;
     201                 :            :                 sal_uInt32 nCodedSize, nUncodedSize;
     202                 :            :                 sal_uLong   nCodedPos;
     203                 :            : 
     204                 :            :                 // read coding information
     205 [ #  # ][ #  # ]:          0 :                 rIStm >> nCodedSize >> nUncodedSize >> aHeader.nCompression;
                 [ #  # ]
     206                 :          0 :                 pData = (sal_uInt8*) rtl_allocateMemory( nUncodedSize );
     207                 :            : 
     208                 :            :                 // decode buffer
     209                 :          0 :                 nCodedPos = rIStm.Tell();
     210         [ #  # ]:          0 :                 aCodec.BeginCompression();
     211         [ #  # ]:          0 :                 aCodec.Read( rIStm, pData, nUncodedSize );
     212         [ #  # ]:          0 :                 aCodec.EndCompression();
     213                 :            : 
     214                 :            :                 // skip unread bytes from coded buffer
     215         [ #  # ]:          0 :                 rIStm.SeekRel( nCodedSize - ( rIStm.Tell() - nCodedPos ) );
     216                 :            : 
     217                 :            :                 // set decoded bytes to memory stream,
     218                 :            :                 // from which we will read the bitmap data
     219 [ #  # ][ #  # ]:          0 :                 pMemStm = new SvMemoryStream;
     220                 :          0 :                 pIStm = pMemStm;
     221         [ #  # ]:          0 :                 pMemStm->SetBuffer( (char*) pData, nUncodedSize, sal_False, nUncodedSize );
     222         [ #  # ]:          0 :                 nOffset = 0;
     223                 :            :             }
     224                 :            :             else
     225                 :         46 :                 pIStm = &rIStm;
     226                 :            : 
     227                 :            :             // read palette
     228         [ +  + ]:         46 :             if( nColors )
     229                 :            :             {
     230         [ +  - ]:         27 :                 pAcc->SetPaletteEntryCount( nColors );
     231         [ +  - ]:         27 :                 ImplReadDIBPalette( *pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE );
     232                 :            :             }
     233                 :            : 
     234                 :            :             // read bits
     235         [ +  - ]:         46 :             if( !pIStm->GetError() )
     236                 :            :             {
     237         [ +  - ]:         46 :                 if( nOffset )
     238         [ +  - ]:         46 :                     pIStm->SeekRel( nOffset - ( pIStm->Tell() - nStmPos ) );
     239                 :            : 
     240         [ +  - ]:         46 :                 bRet = ImplReadDIBBits( *pIStm, aHeader, *pAcc, bTopDown );
     241                 :            : 
     242 [ +  - ][ +  + ]:         46 :                 if( bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter )
                 [ +  - ]
     243                 :            :                 {
     244                 :            :                     MapMode aMapMode( MAP_MM, Point(),
     245                 :            :                                       Fraction( 1000, aHeader.nXPelsPerMeter ),
     246 [ +  - ][ +  - ]:         21 :                                       Fraction( 1000, aHeader.nYPelsPerMeter ) );
                 [ +  - ]
     247                 :            : 
     248         [ +  - ]:         21 :                     aNewBmp.SetPrefMapMode( aMapMode );
     249         [ +  - ]:         21 :                     aNewBmp.SetPrefSize( Size( aHeader.nWidth, abs(aHeader.nHeight) ) );
     250                 :            :                 }
     251                 :            :             }
     252                 :            : 
     253         [ -  + ]:         46 :             if( pData )
     254                 :          0 :                 rtl_freeMemory( pData );
     255                 :            : 
     256 [ -  + ][ #  # ]:         46 :             delete pMemStm;
     257         [ +  - ]:         46 :             aNewBmp.ReleaseAccess( pAcc );
     258                 :            : 
     259         [ +  - ]:         46 :             if( bRet )
     260         [ +  - ]:         46 :                 rBmp = aNewBmp;
     261         [ +  - ]:         46 :         }
     262                 :            :     }
     263                 :            : 
     264                 :        159 :     return bRet;
     265                 :            : }
     266                 :            : 
     267                 :            : // ------------------------------------------------------------------
     268                 :            : 
     269                 :       7064 : sal_Bool Bitmap::ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset )
     270                 :            : {
     271                 :            :     sal_uInt32  nTmp32;
     272                 :       7064 :     sal_uInt16  nTmp16 = 0;
     273                 :       7064 :     sal_Bool    bRet = sal_False;
     274                 :            : 
     275         [ +  - ]:       7064 :     rIStm >> nTmp16;
     276                 :            : 
     277 [ +  + ][ -  + ]:       7064 :     if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) )
     278                 :            :     {
     279         [ -  + ]:        318 :         if ( 0x4142 == nTmp16 )
     280                 :            :         {
     281         [ #  # ]:          0 :             rIStm.SeekRel( 12L );
     282         [ #  # ]:          0 :             rIStm >> nTmp16;
     283         [ #  # ]:          0 :             rIStm.SeekRel( 8L );
     284         [ #  # ]:          0 :             rIStm >> nTmp32;
     285                 :          0 :             rOffset = nTmp32 - 28UL;
     286                 :          0 :             bRet = ( 0x4D42 == nTmp16 );
     287                 :            :         }
     288                 :            :         else
     289                 :            :         {
     290         [ +  - ]:        159 :             rIStm.SeekRel( 8L );
     291         [ +  - ]:        159 :             rIStm >> nTmp32;
     292                 :        159 :             rOffset = nTmp32 - 14UL;
     293                 :        159 :             bRet = ( rIStm.GetError() == 0UL );
     294                 :            :         }
     295                 :            :     }
     296                 :            :     else
     297         [ +  - ]:       6905 :         rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
     298                 :            : 
     299                 :       7064 :     return bRet;
     300                 :            : }
     301                 :            : 
     302                 :            : // ------------------------------------------------------------------
     303                 :            : 
     304                 :        159 : sal_Bool Bitmap::ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader, sal_Bool& bTopDown, sal_Bool bIsMSOFormat )
     305                 :            : {
     306                 :            :     // BITMAPINFOHEADER or BITMAPCOREHEADER
     307         [ +  - ]:        159 :     rIStm >> rHeader.nSize;
     308                 :            : 
     309                 :            :     // BITMAPCOREHEADER
     310                 :        159 :     sal_Int16 nTmp16 = 0;
     311         [ +  + ]:        159 :     if ( rHeader.nSize == DIBCOREHEADERSIZE )
     312                 :            :     {
     313                 :            : 
     314         [ +  - ]:          3 :         rIStm >> nTmp16; rHeader.nWidth = nTmp16;
     315         [ +  - ]:          3 :         rIStm >> nTmp16; rHeader.nHeight = nTmp16;
     316         [ +  - ]:          3 :         rIStm >> rHeader.nPlanes;
     317         [ +  - ]:          3 :         rIStm >> rHeader.nBitCount;
     318                 :            :     }
     319 [ -  + ][ #  # ]:        156 :     else if ( bIsMSOFormat && ( rHeader.nSize == BITMAPINFOHEADER ) )
     320                 :            :     {
     321                 :          0 :         sal_uInt8 nTmp8 = 0;
     322         [ #  # ]:          0 :         rIStm >> nTmp16; rHeader.nWidth = nTmp16;
     323         [ #  # ]:          0 :         rIStm >> nTmp16; rHeader.nHeight = nTmp16;
     324         [ #  # ]:          0 :         rIStm >> nTmp8; rHeader.nPlanes = nTmp8;
     325         [ #  # ]:          0 :         rIStm >> nTmp8; rHeader.nBitCount = nTmp8;
     326         [ #  # ]:          0 :         rIStm >> nTmp16; rHeader.nSizeImage = nTmp16;
     327         [ #  # ]:          0 :         rIStm >> nTmp16; rHeader.nCompression = nTmp16;
     328         [ #  # ]:          0 :         if ( !rHeader.nSizeImage ) // uncompressed?
     329                 :          0 :             rHeader.nSizeImage = ((rHeader.nWidth * rHeader.nBitCount + 31) & ~31) / 8 * rHeader.nHeight;
     330         [ #  # ]:          0 :         rIStm >> rHeader.nXPelsPerMeter;
     331         [ #  # ]:          0 :         rIStm >> rHeader.nYPelsPerMeter;
     332         [ #  # ]:          0 :         rIStm >> rHeader.nColsUsed;
     333         [ #  # ]:          0 :         rIStm >> rHeader.nColsImportant;
     334                 :            :     }
     335                 :            :     else
     336                 :            :     {
     337                 :            :         // unknown Header
     338         [ +  + ]:        156 :         if( rHeader.nSize < DIBINFOHEADERSIZE )
     339                 :            :         {
     340                 :        110 :             sal_uLong nUnknownSize = sizeof( rHeader.nSize );
     341                 :            : 
     342         [ +  - ]:        110 :             rIStm >> rHeader.nWidth; nUnknownSize += sizeof( rHeader.nWidth );
     343         [ +  - ]:        110 :             rIStm >> rHeader.nHeight; nUnknownSize += sizeof( rHeader.nHeight );
     344         [ +  - ]:        110 :             rIStm >> rHeader.nPlanes; nUnknownSize += sizeof( rHeader.nPlanes );
     345         [ +  - ]:        110 :             rIStm >> rHeader.nBitCount; nUnknownSize += sizeof( rHeader.nBitCount );
     346                 :            : 
     347         [ -  + ]:        110 :             if( nUnknownSize < rHeader.nSize )
     348                 :            :             {
     349         [ #  # ]:          0 :                 rIStm >> rHeader.nCompression;
     350                 :          0 :                 nUnknownSize += sizeof( rHeader.nCompression );
     351                 :            : 
     352         [ #  # ]:          0 :                 if( nUnknownSize < rHeader.nSize )
     353                 :            :                 {
     354         [ #  # ]:          0 :                     rIStm >> rHeader.nSizeImage;
     355                 :          0 :                     nUnknownSize += sizeof( rHeader.nSizeImage );
     356                 :            : 
     357         [ #  # ]:          0 :                     if( nUnknownSize < rHeader.nSize )
     358                 :            :                     {
     359         [ #  # ]:          0 :                         rIStm >> rHeader.nXPelsPerMeter;
     360                 :          0 :                         nUnknownSize += sizeof( rHeader.nXPelsPerMeter );
     361                 :            : 
     362         [ #  # ]:          0 :                         if( nUnknownSize < rHeader.nSize )
     363                 :            :                         {
     364         [ #  # ]:          0 :                             rIStm >> rHeader.nYPelsPerMeter;
     365                 :          0 :                             nUnknownSize += sizeof( rHeader.nYPelsPerMeter );
     366                 :            :                         }
     367                 :            : 
     368         [ #  # ]:          0 :                         if( nUnknownSize < rHeader.nSize )
     369                 :            :                         {
     370         [ #  # ]:          0 :                             rIStm >> rHeader.nColsUsed;
     371                 :          0 :                             nUnknownSize += sizeof( rHeader.nColsUsed );
     372                 :            : 
     373         [ #  # ]:          0 :                             if( nUnknownSize < rHeader.nSize )
     374                 :            :                             {
     375         [ #  # ]:          0 :                                 rIStm >> rHeader.nColsImportant;
     376                 :          0 :                                 nUnknownSize += sizeof( rHeader.nColsImportant );
     377                 :            :                             }
     378                 :            :                         }
     379                 :            :                     }
     380                 :            :                 }
     381                 :            :             }
     382                 :            :         }
     383                 :            :         else
     384                 :            :         {
     385         [ +  - ]:         46 :             rIStm >> rHeader.nWidth;
     386         [ +  - ]:         46 :             rIStm >> rHeader.nHeight; //rHeader.nHeight=abs(rHeader.nHeight);
     387         [ +  - ]:         46 :             rIStm >> rHeader.nPlanes;
     388         [ +  - ]:         46 :             rIStm >> rHeader.nBitCount;
     389         [ +  - ]:         46 :             rIStm >> rHeader.nCompression;
     390         [ +  - ]:         46 :             rIStm >> rHeader.nSizeImage;
     391         [ +  - ]:         46 :             rIStm >> rHeader.nXPelsPerMeter;
     392         [ +  - ]:         46 :             rIStm >> rHeader.nYPelsPerMeter;
     393         [ +  - ]:         46 :             rIStm >> rHeader.nColsUsed;
     394         [ +  - ]:         46 :             rIStm >> rHeader.nColsImportant;
     395                 :            :         }
     396                 :            : 
     397                 :            :         // Eventuell bis zur Palette ueberlesen
     398         [ -  + ]:        156 :         if ( rHeader.nSize > DIBINFOHEADERSIZE )
     399         [ #  # ]:          0 :             rIStm.SeekRel( rHeader.nSize - DIBINFOHEADERSIZE );
     400                 :            :     }
     401         [ -  + ]:        159 :     if ( rHeader.nHeight < 0 )
     402                 :            :     {
     403                 :          0 :         bTopDown = sal_True;
     404                 :          0 :         rHeader.nHeight *= -1;
     405                 :            :     }
     406                 :            :     else
     407                 :        159 :         bTopDown = sal_False;
     408                 :            : 
     409         [ -  + ]:        159 :     if ( rHeader.nWidth < 0 )
     410         [ #  # ]:          0 :         rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
     411                 :            : 
     412                 :            :     // #144105# protect a little against damaged files
     413         [ -  + ]:        159 :     if( rHeader.nSizeImage > ( 16 * static_cast< sal_uInt32 >( rHeader.nWidth * rHeader.nHeight ) ) )
     414                 :          0 :         rHeader.nSizeImage = 0;
     415                 :            : 
     416 [ +  + ][ +  - ]:        159 :     return( ( rHeader.nPlanes == 1 ) && ( rIStm.GetError() == 0UL ) );
     417                 :            : }
     418                 :            : 
     419                 :            : // ------------------------------------------------------------------
     420                 :            : 
     421                 :         27 : sal_Bool Bitmap::ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, sal_Bool bQuad )
     422                 :            : {
     423                 :         27 :     const sal_uInt16    nColors = rAcc.GetPaletteEntryCount();
     424         [ +  - ]:         27 :     const sal_uLong     nPalSize = nColors * ( bQuad ? 4UL : 3UL );
     425                 :         27 :     BitmapColor     aPalColor;
     426                 :            : 
     427         [ +  - ]:         27 :     sal_uInt8* pEntries = new sal_uInt8[ nPalSize ];
     428         [ +  - ]:         27 :     rIStm.Read( pEntries, nPalSize );
     429                 :            : 
     430                 :         27 :     sal_uInt8* pTmpEntry = pEntries;
     431         [ +  + ]:       3495 :     for( sal_uInt16 i = 0; i < nColors; i++ )
     432                 :            :     {
     433                 :       3468 :         aPalColor.SetBlue( *pTmpEntry++ );
     434                 :       3468 :         aPalColor.SetGreen( *pTmpEntry++ );
     435                 :       3468 :         aPalColor.SetRed( *pTmpEntry++ );
     436                 :            : 
     437         [ +  - ]:       3468 :         if( bQuad )
     438                 :       3468 :             pTmpEntry++;
     439                 :            : 
     440                 :       3468 :         rAcc.SetPaletteColor( i, aPalColor );
     441                 :            :     }
     442                 :            : 
     443         [ +  - ]:         27 :     delete[] pEntries;
     444                 :            : 
     445                 :         27 :     return( rIStm.GetError() == 0UL );
     446                 :            : }
     447                 :            : 
     448                 :            : // ------------------------------------------------------------------
     449                 :            : 
     450                 :         46 : sal_Bool Bitmap::ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc, sal_Bool bTopDown )
     451                 :            : {
     452                 :         46 :     const sal_uLong nAlignedWidth = AlignedWidth4Bytes( rHeader.nWidth * rHeader.nBitCount );
     453                 :         46 :     sal_uInt32      nRMask = 0;
     454                 :         46 :     sal_uInt32      nGMask = 0;
     455                 :         46 :     sal_uInt32      nBMask = 0;
     456                 :            :     sal_Bool        bNative;
     457 [ -  + ][ +  - ]:         46 :     sal_Bool        bTCMask = ( rHeader.nBitCount == 16 ) || ( rHeader.nBitCount == 32 );
     458                 :            :     sal_Bool        bRLE = ( RLE_8 == rHeader.nCompression && rHeader.nBitCount == 8 ) ||
     459 [ +  + ][ -  + ]:         46 :                        ( RLE_4 == rHeader.nCompression && rHeader.nBitCount == 4 );
         [ -  + ][ #  # ]
     460                 :            : 
     461                 :            :     // Is native format?
     462         [ +  - ]:         46 :     switch( rAcc.GetScanlineFormat() )
     463                 :            :     {
     464                 :            :         case( BMP_FORMAT_1BIT_MSB_PAL ):
     465                 :            :         case( BMP_FORMAT_4BIT_MSN_PAL ):
     466                 :            :         case( BMP_FORMAT_8BIT_PAL ):
     467                 :            :         case( BMP_FORMAT_24BIT_TC_BGR ):
     468 [ +  - ][ +  - ]:         46 :             bNative = ( ( rAcc.IsBottomUp() != bTopDown ) && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) );
         [ +  + ][ +  - ]
                 [ +  + ]
     469                 :         46 :         break;
     470                 :            : 
     471                 :            :         default:
     472                 :          0 :             bNative = sal_False;
     473                 :          0 :         break;
     474                 :            :     }
     475                 :            :     // Read data
     476         [ +  + ]:         46 :     if( bNative )
     477                 :            :     {
     478                 :            :         // true color DIB's can have a (optimization) palette
     479 [ +  + ][ -  + ]:         25 :         if( rHeader.nColsUsed && rHeader.nBitCount > 8 )
     480 [ #  # ][ #  # ]:          0 :             rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) );
     481                 :            : 
     482         [ +  - ]:         25 :         if ( rHeader.nHeight > 0 )
     483         [ +  - ]:         25 :             rIStm.Read( rAcc.GetBuffer(), rHeader.nHeight * nAlignedWidth );
     484                 :            :         else
     485                 :            :         {
     486         [ #  # ]:          0 :             for( int i = abs(rHeader.nHeight)-1; i >= 0; i-- )
     487         [ #  # ]:          0 :                 rIStm.Read( ((char*)rAcc.GetBuffer()) + (nAlignedWidth*i), nAlignedWidth );
     488                 :            :         }
     489                 :            :     }
     490                 :            :     else
     491                 :            :     {
     492                 :            :         // Read color mask
     493         [ -  + ]:         21 :         if( bTCMask )
     494                 :            :         {
     495         [ #  # ]:          0 :             if( rHeader.nCompression == BITFIELDS )
     496                 :            :             {
     497         [ #  # ]:          0 :                 rIStm.SeekRel( -12L );
     498         [ #  # ]:          0 :                 rIStm >> nRMask;
     499         [ #  # ]:          0 :                 rIStm >> nGMask;
     500         [ #  # ]:          0 :                 rIStm >> nBMask;
     501                 :            :             }
     502                 :            :             else
     503                 :            :             {
     504         [ #  # ]:          0 :                 nRMask = ( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL;
     505         [ #  # ]:          0 :                 nGMask = ( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL;
     506         [ #  # ]:          0 :                 nBMask = ( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL;
     507                 :            :             }
     508                 :            :         }
     509                 :            : 
     510         [ +  + ]:         21 :         if( bRLE )
     511                 :            :         {
     512         [ -  + ]:         13 :             if ( !rHeader.nSizeImage )
     513                 :            :             {
     514                 :          0 :                 const sal_uLong nOldPos = rIStm.Tell();
     515                 :            : 
     516         [ #  # ]:          0 :                 rIStm.Seek( STREAM_SEEK_TO_END );
     517                 :          0 :                 rHeader.nSizeImage = rIStm.Tell() - nOldPos;
     518         [ #  # ]:          0 :                 rIStm.Seek( nOldPos );
     519                 :            :             }
     520                 :            : 
     521                 :         13 :             sal_uInt8* pBuffer = (sal_uInt8*) rtl_allocateMemory( rHeader.nSizeImage );
     522                 :            : 
     523         [ +  - ]:         13 :             rIStm.Read( (char*) pBuffer, rHeader.nSizeImage );
     524         [ +  - ]:         13 :             ImplDecodeRLE( pBuffer, rHeader, rAcc, RLE_4 == rHeader.nCompression );
     525                 :            : 
     526                 :         13 :             rtl_freeMemory( pBuffer );
     527                 :            :         }
     528                 :            :         else
     529                 :            :         {
     530                 :          8 :             const long  nWidth = rHeader.nWidth;
     531                 :          8 :             const long  nHeight = abs(rHeader.nHeight);
     532         [ +  - ]:          8 :             sal_uInt8*      pBuf = new sal_uInt8[ nAlignedWidth ];
     533                 :            : 
     534                 :            :             // true color DIB's can have a (optimization) palette
     535 [ +  - ][ -  + ]:          8 :             if( rHeader.nColsUsed && rHeader.nBitCount > 8 )
     536 [ #  # ][ #  # ]:          0 :                 rIStm.SeekRel( rHeader.nColsUsed * ( ( rHeader.nSize != DIBCOREHEADERSIZE ) ? 4 : 3 ) );
     537                 :            : 
     538         [ -  + ]:          8 :             const long nI = bTopDown ? 1 : -1;
     539         [ +  - ]:          8 :             long nY = bTopDown ? 0 : nHeight - 1;
     540                 :          8 :             long nCount = nHeight;
     541                 :            : 
     542   [ -  +  -  -  :          8 :             switch( rHeader.nBitCount )
                -  -  - ]
     543                 :            :             {
     544                 :            :                 case( 1 ):
     545                 :            :                 {
     546                 :            :                     sal_uInt8*  pTmp;
     547                 :            :                     sal_uInt8   cTmp;
     548                 :            : 
     549         [ #  # ]:          0 :                     for( ; nCount--; nY += nI )
     550                 :            :                     {
     551         [ #  # ]:          0 :                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
     552                 :          0 :                         cTmp = *pTmp++;
     553                 :            : 
     554         [ #  # ]:          0 :                         for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
     555                 :            :                         {
     556         [ #  # ]:          0 :                             if( !nShift )
     557                 :            :                             {
     558                 :            :                                 nShift = 8L,
     559                 :          0 :                                 cTmp = *pTmp++;
     560                 :            :                             }
     561                 :            : 
     562         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX, sal::static_int_cast<sal_uInt8>(( cTmp >> --nShift ) & 1) );
     563                 :            :                         }
     564                 :            :                     }
     565                 :            :                 }
     566                 :          0 :                 break;
     567                 :            : 
     568                 :            :                 case( 4 ):
     569                 :            :                 {
     570                 :            :                     sal_uInt8*  pTmp;
     571                 :            :                     sal_uInt8   cTmp;
     572                 :            : 
     573         [ +  + ]:        112 :                     for( ; nCount--; nY += nI )
     574                 :            :                     {
     575         [ +  - ]:        104 :                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
     576                 :        104 :                         cTmp = *pTmp++;
     577                 :            : 
     578         [ +  + ]:      10244 :                         for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
     579                 :            :                         {
     580         [ +  + ]:      10140 :                             if( !nShift )
     581                 :            :                             {
     582                 :            :                                 nShift = 2UL,
     583                 :       4992 :                                 cTmp = *pTmp++;
     584                 :            :                             }
     585                 :            : 
     586         [ +  - ]:      10140 :                             rAcc.SetPixel( nY, nX, sal::static_int_cast<sal_uInt8>(( cTmp >> ( --nShift << 2UL ) ) & 0x0f) );
     587                 :            :                         }
     588                 :            :                     }
     589                 :            :                 }
     590                 :          8 :                 break;
     591                 :            : 
     592                 :            :                 case( 8 ):
     593                 :            :                 {
     594                 :            :                     sal_uInt8*  pTmp;
     595                 :            : 
     596         [ #  # ]:          0 :                     for( ; nCount--; nY += nI )
     597                 :            :                     {
     598         [ #  # ]:          0 :                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
     599                 :            : 
     600         [ #  # ]:          0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     601         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX, *pTmp++ );
     602                 :            :                     }
     603                 :            :                 }
     604                 :          0 :                 break;
     605                 :            : 
     606                 :            :                 case( 16 ):
     607                 :            :                 {
     608         [ #  # ]:          0 :                     ColorMask   aMask( nRMask, nGMask, nBMask );
     609                 :          0 :                     BitmapColor aColor;
     610                 :            :                     sal_uInt16*     pTmp16;
     611                 :            : 
     612         [ #  # ]:          0 :                     for( ; nCount--; nY += nI )
     613                 :            :                     {
     614         [ #  # ]:          0 :                         rIStm.Read( (char*)( pTmp16 = (sal_uInt16*) pBuf ), nAlignedWidth );
     615                 :            : 
     616         [ #  # ]:          0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     617                 :            :                         {
     618                 :          0 :                             aMask.GetColorFor16BitLSB( aColor, (sal_uInt8*) pTmp16++ );
     619         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX, aColor );
     620                 :            :                         }
     621                 :          0 :                     }
     622                 :            :                 }
     623                 :          0 :                 break;
     624                 :            : 
     625                 :            :                 case( 24 ):
     626                 :            :                 {
     627                 :          0 :                     BitmapColor aPixelColor;
     628                 :            :                     sal_uInt8*      pTmp;
     629                 :            : 
     630         [ #  # ]:          0 :                     for( ; nCount--; nY += nI )
     631                 :            :                     {
     632         [ #  # ]:          0 :                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
     633                 :            : 
     634         [ #  # ]:          0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     635                 :            :                         {
     636                 :          0 :                             aPixelColor.SetBlue( *pTmp++ );
     637                 :          0 :                             aPixelColor.SetGreen( *pTmp++ );
     638                 :          0 :                             aPixelColor.SetRed( *pTmp++ );
     639         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX, aPixelColor );
     640                 :            :                         }
     641                 :          0 :                     }
     642                 :            :                 }
     643                 :          0 :                 break;
     644                 :            : 
     645                 :            :                 case( 32 ):
     646                 :            :                 {
     647         [ #  # ]:          0 :                     ColorMask   aMask( nRMask, nGMask, nBMask );
     648                 :          0 :                     BitmapColor aColor;
     649                 :            :                     sal_uInt32*     pTmp32;
     650                 :            : 
     651         [ #  # ]:          0 :                     for( ; nCount--; nY += nI )
     652                 :            :                     {
     653         [ #  # ]:          0 :                         rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth );
     654                 :            : 
     655         [ #  # ]:          0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     656                 :            :                         {
     657                 :          0 :                             aMask.GetColorFor32Bit( aColor, (sal_uInt8*) pTmp32++ );
     658         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX, aColor );
     659                 :            :                         }
     660                 :          0 :                     }
     661                 :            :                 }
     662                 :            :             }
     663                 :            : 
     664         [ +  - ]:          8 :             delete[] pBuf;
     665                 :            :         }
     666                 :            :     }
     667                 :            : 
     668                 :         46 :     return( rIStm.GetError() == 0UL );
     669                 :            : }
     670                 :            : 
     671                 :            : // ------------------------------------------------------------------
     672                 :            : 
     673                 :         38 : sal_Bool Bitmap::Write( SvStream& rOStm, sal_Bool bCompressed, sal_Bool bFileHeader ) const
     674                 :            : {
     675                 :            :     DBG_ASSERT( mpImpBmp, "Empty Bitmaps can't be saved" );
     676                 :            : 
     677         [ +  - ]:         38 :     const Size  aSizePix( GetSizePixel() );
     678                 :         38 :     sal_Bool        bRet = sal_False;
     679                 :            : 
     680 [ +  - ][ +  - ]:         38 :     if( mpImpBmp && aSizePix.Width() && aSizePix.Height() )
         [ +  - ][ +  - ]
     681                 :            :     {
     682         [ +  - ]:         38 :         BitmapReadAccess*   pAcc = ( (Bitmap*) this)->AcquireReadAccess();
     683                 :         38 :         const sal_uInt16        nOldFormat = rOStm.GetNumberFormatInt();
     684                 :         38 :         const sal_uLong         nOldPos = rOStm.Tell();
     685                 :            : 
     686         [ +  - ]:         38 :         rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     687                 :            : 
     688         [ +  - ]:         38 :         if( pAcc )
     689                 :            :         {
     690         [ +  + ]:         38 :             if( bFileHeader )
     691                 :            :             {
     692 [ +  - ][ +  - ]:         26 :                 if( ImplWriteDIBFileHeader( rOStm, *pAcc ) )
     693         [ +  - ]:         26 :                     bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed );
     694                 :            :             }
     695                 :            :             else
     696         [ +  - ]:         12 :                 bRet = ImplWriteDIB( rOStm, *pAcc, bCompressed );
     697                 :            : 
     698         [ +  - ]:         38 :             ( (Bitmap*) this)->ReleaseAccess( pAcc );
     699                 :            :         }
     700                 :            : 
     701         [ -  + ]:         38 :         if( !bRet )
     702                 :            :         {
     703         [ #  # ]:          0 :             rOStm.SetError( SVSTREAM_GENERALERROR );
     704         [ #  # ]:          0 :             rOStm.Seek( nOldPos );
     705                 :            :         }
     706                 :            : 
     707         [ +  - ]:         38 :         rOStm.SetNumberFormatInt( nOldFormat );
     708                 :            :     }
     709                 :            : 
     710                 :         38 :     return bRet;
     711                 :            : }
     712                 :            : 
     713                 :            : // ------------------------------------------------------------------
     714                 :            : 
     715                 :         38 : sal_Bool Bitmap::ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bCompressed ) const
     716                 :            : {
     717         [ +  - ]:         38 :     const MapMode   aMapPixel( MAP_PIXEL );
     718                 :         38 :     DIBInfoHeader   aHeader;
     719                 :            :     sal_uLong           nImageSizePos;
     720                 :            :     sal_uLong           nEndPos;
     721                 :         38 :     sal_uInt32      nCompression = 0;
     722                 :         38 :     sal_Bool            bRet = sal_False;
     723                 :            : 
     724                 :         38 :     aHeader.nSize = DIBINFOHEADERSIZE;
     725                 :         38 :     aHeader.nWidth = rAcc.Width();
     726                 :         38 :     aHeader.nHeight = rAcc.Height();
     727                 :         38 :     aHeader.nPlanes = 1;
     728                 :            : 
     729         [ -  + ]:         38 :     if( isBitfieldCompression( rAcc.GetScanlineFormat() ) )
     730                 :            :     {
     731         [ #  # ]:          0 :         aHeader.nBitCount = ( rAcc.GetScanlineFormat() == BMP_FORMAT_16BIT_TC_LSB_MASK ) ? 16 : 32;
     732                 :          0 :         aHeader.nSizeImage = rAcc.Height() * rAcc.GetScanlineSize();
     733                 :            : 
     734                 :          0 :         nCompression = BITFIELDS;
     735                 :            :     }
     736                 :            :     else
     737                 :            :     {
     738                 :            :         // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are
     739                 :            :         // not handled properly below (would have to set color
     740                 :            :         // masks, and nCompression=BITFIELDS - but color mask is
     741                 :            :         // not set for formats != *_TC_*). Note that this very
     742                 :            :         // problem might cause trouble at other places - the
     743                 :            :         // introduction of 32 bit RGBA bitmaps is relatively
     744                 :            :         // recent.
     745                 :            :         // #i59239# discretize bitcount to 1,4,8,24 (other cases
     746                 :            :         // are not written below)
     747                 :         38 :         const sal_uInt16 nBitCount( sal::static_int_cast<sal_uInt16>(rAcc.GetBitCount()) );
     748                 :            : 
     749                 :         38 :         aHeader.nBitCount = discretizeBitcount( nBitCount );
     750                 :         38 :         aHeader.nSizeImage = rAcc.Height() *
     751                 :         38 :             AlignedWidth4Bytes( rAcc.Width()*aHeader.nBitCount );
     752                 :            : 
     753         [ +  - ]:         38 :         if( bCompressed )
     754                 :            :         {
     755         [ -  + ]:         38 :             if( 4 == nBitCount )
     756                 :          0 :                 nCompression = RLE_4;
     757         [ +  + ]:         38 :             else if( 8 == nBitCount )
     758                 :         13 :                 nCompression = RLE_8;
     759                 :            :         }
     760                 :            :         else
     761                 :          0 :             nCompression = COMPRESS_NONE;
     762                 :            :     }
     763                 :            : 
     764   [ -  +  #  # ]:         38 :     if( ( rOStm.GetCompressMode() & COMPRESSMODE_ZBITMAP ) &&
                 [ -  + ]
     765                 :          0 :         ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_40 ) )
     766                 :            :     {
     767                 :          0 :         aHeader.nCompression = ZCOMPRESS;
     768                 :            :     }
     769                 :            :     else
     770                 :         38 :         aHeader.nCompression = nCompression;
     771                 :            : 
     772 [ +  + ][ +  - ]:         38 :     if( maPrefSize.Width() && maPrefSize.Height() && ( maPrefMapMode != aMapPixel ) )
         [ +  - ][ +  - ]
                 [ +  + ]
     773                 :            :     {
     774                 :            :         // #i48108# Try to recover xpels/ypels as previously stored on
     775                 :            :         // disk. The problem with just converting maPrefSize to 100th
     776                 :            :         // mm and then relating that to the bitmap pixel size is that
     777                 :            :         // MapMode is integer-based, and suffers from roundoffs,
     778                 :            :         // especially if maPrefSize is small. Trying to circumvent
     779                 :            :         // that by performing part of the math in floating point.
     780                 :            :         const Size aScale100000(
     781                 :            :             OutputDevice::LogicToLogic( Size(100000L,
     782                 :            :                                              100000L),
     783                 :            :                                         MAP_100TH_MM,
     784 [ +  - ][ +  - ]:         13 :                                         maPrefMapMode ) );
                 [ +  - ]
     785                 :         13 :         const double fBmpWidthM((double)maPrefSize.Width() / aScale100000.Width() );
     786                 :         13 :         const double fBmpHeightM((double)maPrefSize.Height() / aScale100000.Height() );
     787 [ +  - ][ +  - ]:         13 :         if( fabs(fBmpWidthM) > 0.000000001 &&
     788                 :         13 :             fabs(fBmpHeightM) > 0.000000001 )
     789                 :            :         {
     790                 :         13 :             aHeader.nXPelsPerMeter = (sal_uInt32)(rAcc.Width() / fBmpWidthM + .5);
     791                 :         13 :             aHeader.nYPelsPerMeter = (sal_uInt32)(rAcc.Height() / fBmpHeightM + .5);
     792                 :            :         }
     793                 :            :     }
     794                 :            : 
     795         [ +  + ]:         38 :     aHeader.nColsUsed = ( ( aHeader.nBitCount <= 8 ) ? rAcc.GetPaletteEntryCount() : 0 );
     796                 :         38 :     aHeader.nColsImportant = 0;
     797                 :            : 
     798         [ +  - ]:         38 :     rOStm << aHeader.nSize;
     799         [ +  - ]:         38 :     rOStm << aHeader.nWidth;
     800         [ +  - ]:         38 :     rOStm << aHeader.nHeight;
     801         [ +  - ]:         38 :     rOStm << aHeader.nPlanes;
     802         [ +  - ]:         38 :     rOStm << aHeader.nBitCount;
     803         [ +  - ]:         38 :     rOStm << aHeader.nCompression;
     804                 :            : 
     805                 :         38 :     nImageSizePos = rOStm.Tell();
     806         [ +  - ]:         38 :     rOStm.SeekRel( sizeof( aHeader.nSizeImage ) );
     807                 :            : 
     808         [ +  - ]:         38 :     rOStm << aHeader.nXPelsPerMeter;
     809         [ +  - ]:         38 :     rOStm << aHeader.nYPelsPerMeter;
     810         [ +  - ]:         38 :     rOStm << aHeader.nColsUsed;
     811         [ +  - ]:         38 :     rOStm << aHeader.nColsImportant;
     812                 :            : 
     813         [ -  + ]:         38 :     if( aHeader.nCompression == ZCOMPRESS )
     814                 :            :     {
     815         [ #  # ]:          0 :         ZCodec          aCodec;
     816         [ #  # ]:          0 :         SvMemoryStream  aMemStm( aHeader.nSizeImage + 4096, 65535 );
     817                 :          0 :         sal_uLong           nCodedPos = rOStm.Tell(), nLastPos;
     818                 :            :         sal_uInt32      nCodedSize, nUncodedSize;
     819                 :            : 
     820                 :            :         // write uncoded data palette
     821         [ #  # ]:          0 :         if( aHeader.nColsUsed )
     822         [ #  # ]:          0 :             ImplWriteDIBPalette( aMemStm, rAcc );
     823                 :            : 
     824                 :            :         // write uncoded bits
     825         [ #  # ]:          0 :         bRet = ImplWriteDIBBits( aMemStm, rAcc, nCompression, aHeader.nSizeImage );
     826                 :            : 
     827                 :            :         // get uncoded size
     828                 :          0 :         nUncodedSize = aMemStm.Tell();
     829                 :            : 
     830                 :            :         // seek over compress info
     831         [ #  # ]:          0 :         rOStm.SeekRel( 12 );
     832                 :            : 
     833                 :            :         // write compressed data
     834         [ #  # ]:          0 :         aCodec.BeginCompression( 3 );
     835 [ #  # ][ #  # ]:          0 :         aCodec.Write( rOStm, (sal_uInt8*) aMemStm.GetData(), nUncodedSize );
     836         [ #  # ]:          0 :         aCodec.EndCompression();
     837                 :            : 
     838                 :            :         // update compress info ( coded size, uncoded size, uncoded compression )
     839                 :          0 :         nCodedSize = ( nLastPos = rOStm.Tell() ) - nCodedPos - 12;
     840         [ #  # ]:          0 :         rOStm.Seek( nCodedPos );
     841 [ #  # ][ #  # ]:          0 :         rOStm << nCodedSize << nUncodedSize << nCompression;
                 [ #  # ]
     842         [ #  # ]:          0 :         rOStm.Seek( nLastPos );
     843                 :            : 
     844         [ #  # ]:          0 :         if( bRet )
     845 [ #  # ][ #  # ]:          0 :             bRet = ( rOStm.GetError() == ERRCODE_NONE );
     846                 :            :     }
     847                 :            :     else
     848                 :            :     {
     849         [ +  + ]:         38 :         if( aHeader.nColsUsed )
     850         [ +  - ]:         19 :             ImplWriteDIBPalette( rOStm, rAcc );
     851                 :            : 
     852         [ +  - ]:         38 :         bRet = ImplWriteDIBBits( rOStm, rAcc, aHeader.nCompression, aHeader.nSizeImage );
     853                 :            :     }
     854                 :            : 
     855                 :         38 :     nEndPos = rOStm.Tell();
     856         [ +  - ]:         38 :     rOStm.Seek( nImageSizePos );
     857         [ +  - ]:         38 :     rOStm << aHeader.nSizeImage;
     858         [ +  - ]:         38 :     rOStm.Seek( nEndPos );
     859                 :            : 
     860         [ +  - ]:         38 :     return bRet;
     861                 :            : }
     862                 :            : 
     863                 :            : // ------------------------------------------------------------------
     864                 :            : 
     865                 :         26 : sal_Bool Bitmap::ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc )
     866                 :            : {
     867                 :         39 :     sal_uInt32  nPalCount = ( rAcc.HasPalette() ? rAcc.GetPaletteEntryCount() :
     868 [ -  + ][ +  + ]:         39 :                           isBitfieldCompression( rAcc.GetScanlineFormat() ) ? 3UL : 0UL );
     869                 :         26 :     sal_uInt32  nOffset = 14 + DIBINFOHEADERSIZE + nPalCount * 4UL;
     870                 :            : 
     871                 :         26 :     rOStm << (sal_uInt16) 0x4D42;
     872                 :         26 :     rOStm << (sal_uInt32) ( nOffset + ( rAcc.Height() * rAcc.GetScanlineSize() ) );
     873                 :         26 :     rOStm << (sal_uInt16) 0;
     874                 :         26 :     rOStm << (sal_uInt16) 0;
     875                 :         26 :     rOStm << nOffset;
     876                 :            : 
     877                 :         26 :     return( rOStm.GetError() == 0UL );
     878                 :            : }
     879                 :            : 
     880                 :            : // ------------------------------------------------------------------
     881                 :            : 
     882                 :         19 : sal_Bool Bitmap::ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc )
     883                 :            : {
     884                 :         19 :     const sal_uInt16    nColors = rAcc.GetPaletteEntryCount();
     885                 :         19 :     const sal_uLong     nPalSize = nColors * 4UL;
     886         [ +  - ]:         19 :     sal_uInt8*          pEntries = new sal_uInt8[ nPalSize ];
     887                 :         19 :     sal_uInt8*          pTmpEntry = pEntries;
     888                 :         19 :     BitmapColor     aPalColor;
     889                 :            : 
     890         [ +  + ]:       3359 :     for( sal_uInt16 i = 0; i < nColors; i++ )
     891                 :            :     {
     892                 :       3340 :         const BitmapColor& rPalColor = rAcc.GetPaletteColor( i );
     893                 :            : 
     894                 :       3340 :         *pTmpEntry++ = rPalColor.GetBlue();
     895                 :       3340 :         *pTmpEntry++ = rPalColor.GetGreen();
     896                 :       3340 :         *pTmpEntry++ = rPalColor.GetRed();
     897                 :       3340 :         *pTmpEntry++ = 0;
     898                 :            :     }
     899                 :            : 
     900         [ +  - ]:         19 :     rOStm.Write( pEntries, nPalSize );
     901         [ +  - ]:         19 :     delete[] pEntries;
     902                 :            : 
     903                 :         19 :     return( rOStm.GetError() == 0UL );
     904                 :            : }
     905                 :            : 
     906                 :            : // ------------------------------------------------------------------
     907                 :            : 
     908                 :            : #if defined(HAVE_MEMCHECK_H)
     909                 :            : namespace
     910                 :            : {
     911                 :            :     void blankExtraSpace(sal_uInt8 *pBits, long nWidth, long nScanlineSize, int nBitCount)
     912                 :            :     {
     913                 :            :         size_t nExtraSpaceInScanLine = nScanlineSize - nWidth * nBitCount / 8;
     914                 :            :         if (nExtraSpaceInScanLine)
     915                 :            :             memset(pBits + (nScanlineSize - nExtraSpaceInScanLine), 0, nExtraSpaceInScanLine);
     916                 :            :     }
     917                 :            : }
     918                 :            : #endif
     919                 :            : 
     920                 :         38 : sal_Bool Bitmap::ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc,
     921                 :            :                                sal_uLong nCompression, sal_uInt32& rImageSize )
     922                 :            : {
     923         [ -  + ]:         38 :     if( BITFIELDS == nCompression )
     924                 :            :     {
     925                 :          0 :         const ColorMask&    rMask = rAcc.GetColorMask();
     926                 :            :         SVBT32              aVal32;
     927                 :            : 
     928                 :          0 :         UInt32ToSVBT32( rMask.GetRedMask(), aVal32 );
     929         [ #  # ]:          0 :         rOStm.Write( (sal_uInt8*) aVal32, 4UL );
     930                 :            : 
     931                 :          0 :         UInt32ToSVBT32( rMask.GetGreenMask(), aVal32 );
     932         [ #  # ]:          0 :         rOStm.Write( (sal_uInt8*) aVal32, 4UL );
     933                 :            : 
     934                 :          0 :         UInt32ToSVBT32( rMask.GetBlueMask(), aVal32 );
     935         [ #  # ]:          0 :         rOStm.Write( (sal_uInt8*) aVal32, 4UL );
     936                 :            : 
     937                 :          0 :         rImageSize = rOStm.Tell();
     938                 :            : 
     939 [ #  # ][ #  # ]:          0 :         if( rAcc.IsBottomUp() )
     940         [ #  # ]:          0 :             rOStm.Write( rAcc.GetBuffer(), rAcc.Height() * rAcc.GetScanlineSize() );
     941                 :            :         else
     942                 :            :         {
     943         [ #  # ]:          0 :             for( long nY = rAcc.Height() - 1, nScanlineSize = rAcc.GetScanlineSize(); nY >= 0L; nY-- )
     944         [ #  # ]:          0 :                 rOStm.Write( rAcc.GetScanline( nY ), nScanlineSize );
     945                 :            :         }
     946                 :            :     }
     947 [ +  - ][ +  + ]:         38 :     else if( ( RLE_4 == nCompression ) || ( RLE_8 == nCompression ) )
     948                 :            :     {
     949                 :         13 :         rImageSize = rOStm.Tell();
     950                 :         13 :         ImplWriteRLE( rOStm, rAcc, RLE_4 == nCompression );
     951                 :            :     }
     952         [ +  - ]:         25 :     else if( !nCompression )
     953                 :            :     {
     954                 :            :         // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are not
     955                 :            :         // handled properly below (would have to set color masks, and
     956                 :            :         // nCompression=BITFIELDS - but color mask is not set for
     957                 :            :         // formats != *_TC_*). Note that this very problem might cause
     958                 :            :         // trouble at other places - the introduction of 32 bit RGBA
     959                 :            :         // bitmaps is relatively recent.
     960                 :            :         // #i59239# discretize bitcount for aligned width to 1,4,8,24
     961                 :            :         // (other cases are not written below)
     962                 :         25 :         const sal_uInt16 nBitCount( sal::static_int_cast<sal_uInt16>(rAcc.GetBitCount()) );
     963                 :         25 :         const sal_uLong  nAlignedWidth = AlignedWidth4Bytes( rAcc.Width() *
     964                 :         25 :                                                          discretizeBitcount(nBitCount));
     965                 :         25 :         sal_Bool         bNative = sal_False;
     966                 :            : 
     967         [ +  - ]:         25 :         switch( rAcc.GetScanlineFormat() )
     968                 :            :         {
     969                 :            :             case( BMP_FORMAT_1BIT_MSB_PAL ):
     970                 :            :             case( BMP_FORMAT_4BIT_MSN_PAL ):
     971                 :            :             case( BMP_FORMAT_8BIT_PAL ):
     972                 :            :             case( BMP_FORMAT_24BIT_TC_BGR ):
     973                 :            :             {
     974 [ +  - ][ +  - ]:         25 :                 if( rAcc.IsBottomUp() && ( rAcc.GetScanlineSize() == nAlignedWidth ) )
                 [ +  - ]
     975                 :         25 :                     bNative = sal_True;
     976                 :            :             }
     977                 :         25 :             break;
     978                 :            : 
     979                 :            :             default:
     980                 :          0 :             break;
     981                 :            :         }
     982                 :            : 
     983                 :         25 :         rImageSize = rOStm.Tell();
     984                 :            : 
     985         [ +  - ]:         25 :         if( bNative )
     986                 :         25 :             rOStm.Write( rAcc.GetBuffer(), nAlignedWidth * rAcc.Height() );
     987                 :            :         else
     988                 :            :         {
     989                 :          0 :             const long  nWidth = rAcc.Width();
     990                 :          0 :             const long  nHeight = rAcc.Height();
     991                 :          0 :             sal_uInt8*      pBuf = new sal_uInt8[ nAlignedWidth ];
     992                 :            : #if defined(HAVE_MEMCHECK_H)
     993                 :            :             if (RUNNING_ON_VALGRIND)
     994                 :            :                 blankExtraSpace(pBuf, nWidth, nAlignedWidth, discretizeBitcount(nBitCount));
     995                 :            : #endif
     996                 :            :             sal_uInt8*      pTmp;
     997                 :            :             sal_uInt8       cTmp;
     998                 :            : 
     999   [ #  #  #  # ]:          0 :             switch( nBitCount )
    1000                 :            :             {
    1001                 :            :                 case( 1 ):
    1002                 :            :                 {
    1003         [ #  # ]:          0 :                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
    1004                 :            :                     {
    1005                 :          0 :                         pTmp = pBuf;
    1006                 :          0 :                         cTmp = 0;
    1007                 :            : 
    1008         [ #  # ]:          0 :                         for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
    1009                 :            :                         {
    1010         [ #  # ]:          0 :                             if( !nShift )
    1011                 :            :                             {
    1012                 :          0 :                                 nShift = 8L;
    1013                 :          0 :                                 *pTmp++ = cTmp;
    1014                 :          0 :                                 cTmp = 0;
    1015                 :            :                             }
    1016                 :            : 
    1017                 :          0 :                             cTmp |= ( (sal_uInt8) rAcc.GetPixel( nY, nX ) << --nShift );
    1018                 :            :                         }
    1019                 :            : 
    1020                 :          0 :                         *pTmp = cTmp;
    1021                 :          0 :                         rOStm.Write( pBuf, nAlignedWidth );
    1022                 :            :                     }
    1023                 :            :                 }
    1024                 :          0 :                 break;
    1025                 :            : 
    1026                 :            :                 case( 4 ):
    1027                 :            :                 {
    1028         [ #  # ]:          0 :                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
    1029                 :            :                     {
    1030                 :          0 :                         pTmp = pBuf;
    1031                 :          0 :                         cTmp = 0;
    1032                 :            : 
    1033         [ #  # ]:          0 :                         for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
    1034                 :            :                         {
    1035         [ #  # ]:          0 :                             if( !nShift )
    1036                 :            :                             {
    1037                 :          0 :                                 nShift = 2L;
    1038                 :          0 :                                 *pTmp++ = cTmp;
    1039                 :          0 :                                 cTmp = 0;
    1040                 :            :                             }
    1041                 :            : 
    1042                 :          0 :                             cTmp |= ( (sal_uInt8) rAcc.GetPixel( nY, nX ) << ( --nShift << 2L ) );
    1043                 :            :                         }
    1044                 :          0 :                         *pTmp = cTmp;
    1045                 :          0 :                         rOStm.Write( pBuf, nAlignedWidth );
    1046                 :            :                     }
    1047                 :            :                 }
    1048                 :          0 :                 break;
    1049                 :            : 
    1050                 :            :                 case( 8 ):
    1051                 :            :                 {
    1052         [ #  # ]:          0 :                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
    1053                 :            :                     {
    1054                 :          0 :                         pTmp = pBuf;
    1055                 :            : 
    1056         [ #  # ]:          0 :                         for( long nX = 0L; nX < nWidth; nX++ )
    1057                 :          0 :                             *pTmp++ = rAcc.GetPixel( nY, nX );
    1058                 :            : 
    1059                 :          0 :                         rOStm.Write( pBuf, nAlignedWidth );
    1060                 :            :                     }
    1061                 :            :                 }
    1062                 :          0 :                 break;
    1063                 :            : 
    1064                 :            :                 // #i59239# fallback to 24 bit format, if bitcount is non-default
    1065                 :            :                 default:
    1066                 :            :                     // FALLTHROUGH intended
    1067                 :            :                 case( 24 ):
    1068                 :            :                 {
    1069                 :          0 :                     BitmapColor aPixelColor;
    1070                 :            : 
    1071         [ #  # ]:          0 :                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
    1072                 :            :                     {
    1073                 :          0 :                         pTmp = pBuf;
    1074                 :            : 
    1075         [ #  # ]:          0 :                         for( long nX = 0L; nX < nWidth; nX++ )
    1076                 :            :                         {
    1077         [ #  # ]:          0 :                             aPixelColor = rAcc.GetPixel( nY, nX );
    1078                 :          0 :                             *pTmp++ = aPixelColor.GetBlue();
    1079                 :          0 :                             *pTmp++ = aPixelColor.GetGreen();
    1080                 :          0 :                             *pTmp++ = aPixelColor.GetRed();
    1081                 :            :                         }
    1082                 :            : 
    1083         [ #  # ]:          0 :                         rOStm.Write( pBuf, nAlignedWidth );
    1084                 :          0 :                     }
    1085                 :            :                 }
    1086                 :          0 :                 break;
    1087                 :            :             }
    1088                 :            : 
    1089         [ #  # ]:          0 :             delete[] pBuf;
    1090                 :            :         }
    1091                 :            :     }
    1092                 :            : 
    1093                 :         38 :     rImageSize = rOStm.Tell() - rImageSize;
    1094                 :            : 
    1095                 :         38 :     return( rOStm.GetError() == 0UL );
    1096                 :            : }
    1097                 :            : 
    1098                 :            : // ------------------------------------------------------------------
    1099                 :            : 
    1100                 :         13 : void Bitmap::ImplDecodeRLE( sal_uInt8* pBuffer, DIBInfoHeader& rHeader,
    1101                 :            :                             BitmapWriteAccess& rAcc, sal_Bool bRLE4 )
    1102                 :            : {
    1103                 :         13 :     Scanline    pRLE = pBuffer;
    1104                 :         13 :     long        nY = abs(rHeader.nHeight) - 1L;
    1105                 :         13 :     const sal_uLong nWidth = rAcc.Width();
    1106                 :            :     sal_uLong       nCountByte;
    1107                 :            :     sal_uLong       nRunByte;
    1108                 :         13 :     sal_uLong       nX = 0UL;
    1109                 :            :     sal_uInt8       cTmp;
    1110                 :         13 :     sal_Bool        bEndDecoding = sal_False;
    1111                 :            : 
    1112 [ +  - ][ +  + ]:      45484 :     do
                 [ +  + ]
    1113                 :            :     {
    1114         [ +  + ]:      45484 :         if( ( nCountByte = *pRLE++ ) == 0 )
    1115                 :            :         {
    1116                 :       4513 :             nRunByte = *pRLE++;
    1117                 :            : 
    1118         [ -  + ]:       4513 :             if( nRunByte > 2 )
    1119                 :            :             {
    1120         [ #  # ]:          0 :                 if( bRLE4 )
    1121                 :            :                 {
    1122                 :          0 :                     nCountByte = nRunByte >> 1;
    1123                 :            : 
    1124         [ #  # ]:          0 :                     for( sal_uLong i = 0UL; i < nCountByte; i++ )
    1125                 :            :                     {
    1126                 :          0 :                         cTmp = *pRLE++;
    1127                 :            : 
    1128         [ #  # ]:          0 :                         if( nX < nWidth )
    1129         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX++, cTmp >> 4 );
    1130                 :            : 
    1131         [ #  # ]:          0 :                         if( nX < nWidth )
    1132         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX++, cTmp & 0x0f );
    1133                 :            :                     }
    1134                 :            : 
    1135         [ #  # ]:          0 :                     if( nRunByte & 1 )
    1136                 :            :                     {
    1137         [ #  # ]:          0 :                         if( nX < nWidth )
    1138         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX++, *pRLE >> 4 );
    1139                 :            : 
    1140                 :          0 :                         pRLE++;
    1141                 :            :                     }
    1142                 :            : 
    1143         [ #  # ]:          0 :                     if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
    1144                 :          0 :                         pRLE++;
    1145                 :            :                 }
    1146                 :            :                 else
    1147                 :            :                 {
    1148         [ #  # ]:          0 :                     for( sal_uLong i = 0UL; i < nRunByte; i++ )
    1149                 :            :                     {
    1150         [ #  # ]:          0 :                         if( nX < nWidth )
    1151         [ #  # ]:          0 :                             rAcc.SetPixel( nY, nX++, *pRLE );
    1152                 :            : 
    1153                 :          0 :                         pRLE++;
    1154                 :            :                     }
    1155                 :            : 
    1156         [ #  # ]:          0 :                     if( nRunByte & 1 )
    1157                 :          0 :                         pRLE++;
    1158                 :            :                 }
    1159                 :            :             }
    1160         [ +  - ]:       4513 :             else if( !nRunByte )
    1161                 :            :             {
    1162                 :       4513 :                 nY--;
    1163                 :       4513 :                 nX = 0UL;
    1164                 :            :             }
    1165         [ #  # ]:          0 :             else if( nRunByte == 1 )
    1166                 :          0 :                 bEndDecoding = sal_True;
    1167                 :            :             else
    1168                 :            :             {
    1169                 :          0 :                 nX += *pRLE++;
    1170                 :          0 :                 nY -= *pRLE++;
    1171                 :            :             }
    1172                 :            :         }
    1173                 :            :         else
    1174                 :            :         {
    1175                 :      40971 :             cTmp = *pRLE++;
    1176                 :            : 
    1177         [ -  + ]:      40971 :             if( bRLE4 )
    1178                 :            :             {
    1179                 :          0 :                 nRunByte = nCountByte >> 1;
    1180                 :            : 
    1181         [ #  # ]:          0 :                 for( sal_uLong i = 0UL; i < nRunByte; i++ )
    1182                 :            :                 {
    1183         [ #  # ]:          0 :                     if( nX < nWidth )
    1184         [ #  # ]:          0 :                         rAcc.SetPixel( nY, nX++, cTmp >> 4 );
    1185                 :            : 
    1186         [ #  # ]:          0 :                     if( nX < nWidth )
    1187         [ #  # ]:          0 :                         rAcc.SetPixel( nY, nX++, cTmp & 0x0f );
    1188                 :            :                 }
    1189                 :            : 
    1190 [ #  # ][ #  # ]:          0 :                 if( ( nCountByte & 1 ) && ( nX < nWidth ) )
    1191         [ #  # ]:          0 :                     rAcc.SetPixel( nY, nX++, cTmp >> 4 );
    1192                 :            :             }
    1193                 :            :             else
    1194                 :            :             {
    1195 [ +  + ][ +  - ]:    3506203 :                 for( sal_uLong i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ )
                 [ +  + ]
    1196         [ +  - ]:    3465232 :                     rAcc.SetPixel( nY, nX++, cTmp );
    1197                 :            :             }
    1198                 :            :         }
    1199                 :            :     }
    1200                 :            :     while ( !bEndDecoding && ( nY >= 0L ) );
    1201                 :         13 : }
    1202                 :            : 
    1203                 :            : // ------------------------------------------------------------------
    1204                 :            : 
    1205                 :         13 : sal_Bool Bitmap::ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bRLE4 )
    1206                 :            : {
    1207                 :         13 :     const sal_uLong nWidth = rAcc.Width();
    1208                 :         13 :     const sal_uLong nHeight = rAcc.Height();
    1209                 :            :     sal_uLong       nX;
    1210                 :            :     sal_uLong       nSaveIndex;
    1211                 :            :     sal_uLong       nCount;
    1212                 :            :     sal_uLong       nBufCount;
    1213                 :         13 :     sal_uInt8*      pBuf = new sal_uInt8[ ( nWidth << 1 ) + 2 ];
    1214                 :            :     sal_uInt8*      pTmp;
    1215                 :            :     sal_uInt8       cPix;
    1216                 :            :     sal_uInt8       cLast;
    1217                 :            :     sal_Bool        bFound;
    1218                 :            : 
    1219         [ +  + ]:       4526 :     for ( long nY = nHeight - 1L; nY >= 0L; nY-- )
    1220                 :            :     {
    1221                 :       4513 :         pTmp = pBuf;
    1222                 :       4513 :         nX = nBufCount = 0UL;
    1223                 :            : 
    1224         [ +  + ]:      45440 :         while( nX < nWidth )
    1225                 :            :         {
    1226                 :      40927 :             nCount = 1L;
    1227                 :      40927 :             cPix = rAcc.GetPixel( nY, nX++ );
    1228                 :            : 
    1229 [ +  + ][ +  + ]:    3465188 :             while( ( nX < nWidth ) && ( nCount < 255L ) && ( cPix == rAcc.GetPixel( nY, nX ) ) )
         [ +  - ][ +  + ]
                 [ +  + ]
           [ +  +  #  # ]
    1230                 :            :             {
    1231                 :    3424261 :                 nX++;
    1232                 :    3424261 :                 nCount++;
    1233                 :            :             }
    1234                 :            : 
    1235         [ +  + ]:      40927 :             if ( nCount > 1 )
    1236                 :            :             {
    1237                 :      30597 :                 *pTmp++ = (sal_uInt8) nCount;
    1238         [ -  + ]:      30597 :                 *pTmp++ = ( bRLE4 ? ( ( cPix << 4 ) | cPix ) : cPix );
    1239                 :      30597 :                 nBufCount += 2;
    1240                 :            :             }
    1241                 :            :             else
    1242                 :            :             {
    1243                 :      10330 :                 cLast = cPix;
    1244                 :      10330 :                 nSaveIndex = nX - 1UL;
    1245                 :      10330 :                 bFound = sal_False;
    1246                 :            : 
    1247 [ +  + ][ +  - ]:      17025 :                 while( ( nX < nWidth ) && ( nCount < 256L ) && ( cPix = rAcc.GetPixel( nY, nX ) ) != cLast )
         [ +  - ][ +  + ]
                 [ +  + ]
           [ +  +  #  # ]
    1248                 :            :                 {
    1249                 :       6695 :                     nX++; nCount++;
    1250                 :       6695 :                     cLast = cPix;
    1251                 :       6695 :                     bFound = sal_True;
    1252                 :            :                 }
    1253                 :            : 
    1254         [ +  + ]:      10330 :                 if ( bFound )
    1255                 :       6651 :                     nX--;
    1256                 :            : 
    1257         [ -  + ]:      10330 :                 if ( nCount > 3 )
    1258                 :            :                 {
    1259                 :          0 :                     *pTmp++ = 0;
    1260                 :          0 :                     *pTmp++ = (sal_uInt8) --nCount;
    1261                 :            : 
    1262         [ #  # ]:          0 :                     if( bRLE4 )
    1263                 :            :                     {
    1264         [ #  # ]:          0 :                         for ( sal_uLong i = 0; i < nCount; i++, pTmp++ )
    1265                 :            :                         {
    1266                 :          0 :                             *pTmp = (sal_uInt8) rAcc.GetPixel( nY, nSaveIndex++ ) << 4;
    1267                 :            : 
    1268         [ #  # ]:          0 :                             if ( ++i < nCount )
    1269                 :          0 :                                 *pTmp |= rAcc.GetPixel( nY, nSaveIndex++ );
    1270                 :            :                         }
    1271                 :            : 
    1272                 :          0 :                         nCount = ( nCount + 1 ) >> 1;
    1273                 :            :                     }
    1274                 :            :                     else
    1275                 :            :                     {
    1276         [ #  # ]:          0 :                         for( sal_uLong i = 0UL; i < nCount; i++ )
    1277                 :          0 :                             *pTmp++ = rAcc.GetPixel( nY, nSaveIndex++ );
    1278                 :            :                     }
    1279                 :            : 
    1280         [ #  # ]:          0 :                     if ( nCount & 1 )
    1281                 :            :                     {
    1282                 :          0 :                         *pTmp++ = 0;
    1283                 :          0 :                         nBufCount += ( nCount + 3 );
    1284                 :            :                     }
    1285                 :            :                     else
    1286                 :          0 :                         nBufCount += ( nCount + 2 );
    1287                 :            :                 }
    1288                 :            :                 else
    1289                 :            :                 {
    1290                 :      10330 :                     *pTmp++ = 1;
    1291         [ -  + ]:      10330 :                     *pTmp++ = (sal_uInt8) rAcc.GetPixel( nY, nSaveIndex ) << ( bRLE4 ? 4 : 0 );
    1292                 :            : 
    1293         [ +  + ]:      10330 :                     if ( nCount == 3 )
    1294                 :            :                     {
    1295                 :         44 :                         *pTmp++ = 1;
    1296         [ -  + ]:         44 :                         *pTmp++ = (sal_uInt8) rAcc.GetPixel( nY, ++nSaveIndex ) << ( bRLE4 ? 4 : 0 );
    1297                 :         44 :                         nBufCount += 4;
    1298                 :            :                     }
    1299                 :            :                     else
    1300                 :      10286 :                         nBufCount += 2;
    1301                 :            :                 }
    1302                 :            :             }
    1303                 :            :         }
    1304                 :            : 
    1305                 :       4513 :         pBuf[ nBufCount++ ] = 0;
    1306                 :       4513 :         pBuf[ nBufCount++ ] = 0;
    1307                 :            : 
    1308                 :       4513 :         rOStm.Write( pBuf, nBufCount );
    1309                 :            :     }
    1310                 :            : 
    1311                 :         13 :     rOStm << (sal_uInt8) 0;
    1312                 :         13 :     rOStm << (sal_uInt8) 1;
    1313                 :            : 
    1314         [ +  - ]:         13 :     delete[] pBuf;
    1315                 :            : 
    1316                 :         13 :     return( rOStm.GetError() == 0UL );
    1317                 :            : }
    1318                 :            : 
    1319                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10