LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/gdi - bmpacc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 108 180 60.0 %
Date: 2013-07-09 Functions: 15 17 88.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <vcl/salbtype.hxx>
      22             : #include <vcl/bitmap.hxx>
      23             : #include <vcl/bmpacc.hxx>
      24             : 
      25             : #include <impbmp.hxx>
      26             : 
      27             : #include <string.h>
      28             : 
      29      196355 : BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap, sal_Bool bModify ) :
      30             :             mpBuffer        ( NULL ),
      31             :             mpScanBuf       ( NULL ),
      32             :             mFncGetPixel    ( NULL ),
      33             :             mFncSetPixel    ( NULL ),
      34      196355 :             mbModify        ( bModify )
      35             : {
      36      196355 :     ImplCreate( rBitmap );
      37      196355 : }
      38             : 
      39      385388 : BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap ) :
      40             :             mpBuffer        ( NULL ),
      41             :             mpScanBuf       ( NULL ),
      42             :             mFncGetPixel    ( NULL ),
      43             :             mFncSetPixel    ( NULL ),
      44      385388 :             mbModify        ( sal_False )
      45             : {
      46      385388 :     ImplCreate( rBitmap );
      47      385388 : }
      48             : 
      49     1548874 : BitmapReadAccess::~BitmapReadAccess()
      50             : {
      51      581743 :     ImplDestroy();
      52      967131 : }
      53             : 
      54      581743 : void BitmapReadAccess::ImplCreate( Bitmap& rBitmap )
      55             : {
      56      581743 :     ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
      57             : 
      58             :     DBG_ASSERT( pImpBmp, "Forbidden Access to empty bitmap!" );
      59             : 
      60      581743 :     if( pImpBmp )
      61             :     {
      62      581741 :         if( mbModify && !maBitmap.ImplGetImpBitmap() )
      63             :         {
      64      196353 :             rBitmap.ImplMakeUnique();
      65      196353 :             pImpBmp = rBitmap.ImplGetImpBitmap();
      66             :         }
      67             :         else
      68             :         {
      69             :             DBG_ASSERT( !mbModify || pImpBmp->ImplGetRefCount() == 2,
      70             :                         "Unpredictable results: bitmap is referenced more than once!" );
      71             :         }
      72             : 
      73      581741 :         mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify );
      74             : 
      75      581741 :         if( !mpBuffer )
      76             :         {
      77           4 :             ImpBitmap* pNewImpBmp = new ImpBitmap;
      78             : 
      79           4 :             if( pNewImpBmp->ImplCreate( *pImpBmp, rBitmap.GetBitCount()  ) )
      80             :             {
      81           0 :                 pImpBmp = pNewImpBmp;
      82           0 :                 rBitmap.ImplSetImpBitmap( pImpBmp );
      83           0 :                 mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify );
      84             :             }
      85             :             else
      86           4 :                 delete pNewImpBmp;
      87             :         }
      88             : 
      89      581741 :         if( mpBuffer )
      90             :         {
      91      581737 :             const long  nHeight = mpBuffer->mnHeight;
      92      581737 :             Scanline    pTmpLine = mpBuffer->mpBits;
      93             : 
      94      581737 :             mpScanBuf = new Scanline[ nHeight ];
      95      581737 :             maColorMask = mpBuffer->maColorMask;
      96             : 
      97      581737 :             if( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
      98             :             {
      99           0 :                 for( long nY = 0L; nY < nHeight; nY++, pTmpLine += mpBuffer->mnScanlineSize )
     100           0 :                     mpScanBuf[ nY ] = pTmpLine;
     101             :             }
     102             :             else
     103             :             {
     104    69994897 :                 for( long nY = nHeight - 1; nY >= 0; nY--, pTmpLine += mpBuffer->mnScanlineSize )
     105    69413160 :                     mpScanBuf[ nY ] = pTmpLine;
     106             :             }
     107             : 
     108      581737 :             if( !ImplSetAccessPointers( BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) ) )
     109             :             {
     110           0 :                 delete[] mpScanBuf;
     111           0 :                 mpScanBuf = NULL;
     112             : 
     113           0 :                 pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
     114           0 :                 mpBuffer = NULL;
     115             :             }
     116             :             else
     117      581737 :                 maBitmap = rBitmap;
     118             :         }
     119             :     }
     120      581743 : }
     121             : 
     122      581743 : void BitmapReadAccess::ImplDestroy()
     123             : {
     124      581743 :     ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap();
     125             : 
     126      581743 :     delete[] mpScanBuf;
     127      581743 :     mpScanBuf = NULL;
     128             : 
     129      581743 :     if( mpBuffer && pImpBmp )
     130             :     {
     131      581737 :         pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
     132      581737 :         mpBuffer = NULL;
     133             :     }
     134      581743 : }
     135             : 
     136      581737 : sal_Bool BitmapReadAccess::ImplSetAccessPointers( sal_uLong nFormat )
     137             : {
     138      581737 :     sal_Bool bRet = sal_True;
     139             : 
     140      581737 :     switch( nFormat )
     141             :     {
     142        3786 :         CASE_FORMAT( _1BIT_MSB_PAL )
     143           0 :         CASE_FORMAT( _1BIT_LSB_PAL )
     144         304 :         CASE_FORMAT( _4BIT_MSN_PAL )
     145           0 :         CASE_FORMAT( _4BIT_LSN_PAL )
     146      329074 :         CASE_FORMAT( _8BIT_PAL )
     147           0 :         CASE_FORMAT( _8BIT_TC_MASK )
     148           0 :         CASE_FORMAT( _16BIT_TC_MSB_MASK )
     149           0 :         CASE_FORMAT( _16BIT_TC_LSB_MASK )
     150      248573 :         CASE_FORMAT( _24BIT_TC_BGR )
     151           0 :         CASE_FORMAT( _24BIT_TC_RGB )
     152           0 :         CASE_FORMAT( _24BIT_TC_MASK )
     153           0 :         CASE_FORMAT( _32BIT_TC_ABGR )
     154           0 :         CASE_FORMAT( _32BIT_TC_ARGB )
     155           0 :         CASE_FORMAT( _32BIT_TC_BGRA )
     156           0 :         CASE_FORMAT( _32BIT_TC_RGBA )
     157           0 :         CASE_FORMAT( _32BIT_TC_MASK )
     158             : 
     159             :         default:
     160           0 :             bRet = sal_False;
     161           0 :         break;
     162             :     }
     163             : 
     164      581737 :     return bRet;
     165             : }
     166             : 
     167         277 : void BitmapReadAccess::ImplZeroInitUnusedBits()
     168             : {
     169         277 :     const sal_uInt32 nWidth = Width(), nHeight = Height(), nScanSize = GetScanlineSize();
     170             : 
     171         277 :     if( nWidth && nHeight && nScanSize && GetBuffer() )
     172             :     {
     173             :         sal_uInt32 nBits;
     174             :         bool       bMsb;
     175             : 
     176         277 :         const sal_uLong nScanlineFormat = GetScanlineFormat();
     177         277 :         switch( nScanlineFormat )
     178             :         {
     179             :             case( BMP_FORMAT_1BIT_MSB_PAL ):
     180          28 :                 nBits = 1;
     181          28 :                 bMsb = true;
     182          28 :                 break;
     183             : 
     184             :             case( BMP_FORMAT_1BIT_LSB_PAL ):
     185           0 :                 nBits = 1;
     186           0 :                 bMsb = false;
     187           0 :                 break;
     188             : 
     189             :             case( BMP_FORMAT_4BIT_MSN_PAL ):
     190           9 :                 nBits = 4;
     191           9 :                 bMsb = true;
     192           9 :                 break;
     193             : 
     194             :             case( BMP_FORMAT_4BIT_LSN_PAL ):
     195           0 :                 nBits = 4;
     196           0 :                 bMsb = false;
     197           0 :                 break;
     198             : 
     199             :             case( BMP_FORMAT_8BIT_PAL ):
     200             :             case( BMP_FORMAT_8BIT_TC_MASK ):
     201         182 :                 bMsb = true;
     202         182 :                 nBits = 8;
     203         182 :             break;
     204             : 
     205             :             case( BMP_FORMAT_16BIT_TC_MSB_MASK ):
     206             :             case( BMP_FORMAT_16BIT_TC_LSB_MASK ):
     207           0 :                 bMsb = true;
     208           0 :                 nBits = 16;
     209           0 :             break;
     210             : 
     211             :             case( BMP_FORMAT_24BIT_TC_BGR ):
     212             :             case( BMP_FORMAT_24BIT_TC_RGB ):
     213             :             case( BMP_FORMAT_24BIT_TC_MASK ):
     214          58 :                 bMsb = true;
     215          58 :                 nBits = 24;
     216          58 :             break;
     217             : 
     218             :             case( BMP_FORMAT_32BIT_TC_ABGR ):
     219             :             case( BMP_FORMAT_32BIT_TC_ARGB ):
     220             :             case( BMP_FORMAT_32BIT_TC_BGRA ):
     221             :             case( BMP_FORMAT_32BIT_TC_RGBA ):
     222             :             case( BMP_FORMAT_32BIT_TC_MASK ):
     223           0 :                 bMsb = true;
     224           0 :                 nBits = 32;
     225           0 :             break;
     226             : 
     227             :             default:
     228             :             {
     229             :                 OSL_FAIL( "BitmapWriteAccess::ZeroInitUnusedBits: Unsupported pixel format");
     230           0 :                 nBits = 0;
     231           0 :                 bMsb = true;
     232             :             }
     233           0 :             break;
     234             :         }
     235             : 
     236         277 :         nBits *= nWidth;
     237         277 :         if( nScanSize % 4 || !bMsb )
     238             :         {
     239             :             DBG_ASSERT( 8*nScanSize >= nBits,
     240             :                         "BitmapWriteAccess::ZeroInitUnusedBits: span size smaller than width?!");
     241         113 :             const sal_uInt32 nLeftOverBits = 8*sizeof(sal_uInt8)*nScanSize - nBits;
     242         113 :             if( nLeftOverBits != 0 ) // else there is really nothing to do
     243             :             {
     244          11 :                 const sal_uInt32 nBytes = (nLeftOverBits + 7U) >> 3U;
     245             :                 sal_uInt8        nMask;
     246             : 
     247          11 :                 if( bMsb )
     248          11 :                     nMask = static_cast<sal_uInt8>(0xffU << (nLeftOverBits & 3UL));
     249             :                 else
     250           0 :                     nMask = static_cast<sal_uInt8>(0xffU >> (nLeftOverBits & 3UL));
     251             : 
     252          11 :                 sal_uInt8* pLastBytes = (sal_uInt8*)GetBuffer() + ( nScanSize - nBytes );
     253         166 :                 for( sal_uInt32 i = 0; i < nHeight; i++, pLastBytes += nScanSize )
     254             :                 {
     255         155 :                     *pLastBytes &= nMask;
     256         155 :                     for( sal_uInt32 j = 1; j < nBytes; j++ )
     257           0 :                         pLastBytes[j] = 0;
     258             :                 }
     259         113 :             }
     260             :         }
     261         164 :         else if( nBits & 0x1f )
     262             :         {
     263          29 :             sal_uInt32  nMask = 0xffffffff << ( ( nScanSize << 3 ) - nBits );
     264          29 :             sal_uInt8*      pLast4Bytes = (sal_uInt8*) GetBuffer() + ( nScanSize - 4 );
     265             : 
     266             : #ifdef OSL_LITENDIAN
     267          29 :             nMask = OSL_SWAPDWORD( nMask );
     268             : #endif
     269        3206 :             for( sal_uInt32 i = 0; i < nHeight; i++, pLast4Bytes += nScanSize )
     270        3177 :                 ( *(sal_uInt32*) pLast4Bytes ) &= nMask;
     271             :         }
     272             :     }
     273         277 : }
     274             : 
     275      625188 : sal_uInt16 BitmapReadAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const
     276             : {
     277      625188 :     return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 );
     278             : }
     279             : 
     280      196355 : BitmapWriteAccess::BitmapWriteAccess( Bitmap& rBitmap ) :
     281             :             BitmapReadAccess( rBitmap, sal_True ),
     282             :             mpLineColor     ( NULL ),
     283      196355 :             mpFillColor     ( NULL )
     284             : {
     285      196355 : }
     286             : 
     287      589065 : BitmapWriteAccess::~BitmapWriteAccess()
     288             : {
     289      196355 :     delete mpLineColor;
     290      196355 :     delete mpFillColor;
     291      392710 : }
     292             : 
     293           0 : void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc )
     294             : {
     295             :     DBG_ASSERT( ( nY >= 0 ) && ( nY < mpBuffer->mnHeight ), "y-coordinate in destination out of range!" );
     296             :     DBG_ASSERT( nY < rReadAcc.Height(), "y-coordinate in source out of range!" );
     297             :     DBG_ASSERT( ( HasPalette() && rReadAcc.HasPalette() ) || ( !HasPalette() && !rReadAcc.HasPalette() ), "No copying possible between palette bitmap and TC bitmap!" );
     298             : 
     299           0 :     if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
     300           0 :         ( GetScanlineSize() >= rReadAcc.GetScanlineSize() ) )
     301             :     {
     302           0 :         memcpy( mpScanBuf[ nY ], rReadAcc.GetScanline( nY ), rReadAcc.GetScanlineSize() );
     303             :     }
     304             :     else
     305             :         // TODO: use fastbmp infrastructure
     306           0 :         for( long nX = 0L, nWidth = std::min( mpBuffer->mnWidth, rReadAcc.Width() ); nX < nWidth; nX++ )
     307           0 :             SetPixel( nY, nX, rReadAcc.GetPixel( nY, nX ) );
     308           0 : }
     309             : 
     310             : 
     311       10501 : void BitmapWriteAccess::CopyScanline( long nY, ConstScanline aSrcScanline,
     312             :                                       sal_uLong nSrcScanlineFormat, sal_uLong nSrcScanlineSize )
     313             : {
     314       10501 :     const sal_uLong nFormat = BMP_SCANLINE_FORMAT( nSrcScanlineFormat );
     315             : 
     316             :     DBG_ASSERT( ( nY >= 0 ) && ( nY < mpBuffer->mnHeight ), "y-coordinate in destination out of range!" );
     317             :     DBG_ASSERT( ( HasPalette() && nFormat <= BMP_FORMAT_8BIT_PAL ) ||
     318             :                 ( !HasPalette() && nFormat > BMP_FORMAT_8BIT_PAL ),
     319             :                 "No copying possible between palette and non palette scanlines!" );
     320             : 
     321       10501 :     const sal_uLong nCount = std::min( GetScanlineSize(), nSrcScanlineSize );
     322             : 
     323       10501 :     if( nCount )
     324             :     {
     325       10501 :         if( GetScanlineFormat() == BMP_SCANLINE_FORMAT( nSrcScanlineFormat ) )
     326        7897 :             memcpy( mpScanBuf[ nY ], aSrcScanline, nCount );
     327             :         else
     328             :         {
     329             :             DBG_ASSERT( nFormat != BMP_FORMAT_8BIT_TC_MASK &&
     330             :                         nFormat != BMP_FORMAT_16BIT_TC_MSB_MASK && nFormat != BMP_FORMAT_16BIT_TC_LSB_MASK &&
     331             :                         nFormat != BMP_FORMAT_24BIT_TC_MASK && nFormat != BMP_FORMAT_32BIT_TC_MASK,
     332             :                         "No support for pixel formats with color masks yet!" );
     333             : 
     334             :             // TODO: use fastbmp infrastructure
     335             :             FncGetPixel pFncGetPixel;
     336             : 
     337        2604 :             switch( nFormat )
     338             :             {
     339           0 :                 case( BMP_FORMAT_1BIT_MSB_PAL ):    pFncGetPixel = GetPixelFor_1BIT_MSB_PAL; break;
     340           0 :                 case( BMP_FORMAT_1BIT_LSB_PAL ):    pFncGetPixel = GetPixelFor_1BIT_LSB_PAL; break;
     341           0 :                 case( BMP_FORMAT_4BIT_MSN_PAL ):    pFncGetPixel = GetPixelFor_4BIT_MSN_PAL; break;
     342           0 :                 case( BMP_FORMAT_4BIT_LSN_PAL ):    pFncGetPixel = GetPixelFor_4BIT_LSN_PAL; break;
     343           0 :                 case( BMP_FORMAT_8BIT_PAL ):        pFncGetPixel = GetPixelFor_8BIT_PAL; break;
     344           0 :                 case( BMP_FORMAT_8BIT_TC_MASK ):    pFncGetPixel = GetPixelFor_8BIT_TC_MASK; break;
     345           0 :                 case( BMP_FORMAT_16BIT_TC_MSB_MASK ):   pFncGetPixel = GetPixelFor_16BIT_TC_MSB_MASK; break;
     346           0 :                 case( BMP_FORMAT_16BIT_TC_LSB_MASK ):   pFncGetPixel = GetPixelFor_16BIT_TC_LSB_MASK; break;
     347           0 :                 case( BMP_FORMAT_24BIT_TC_BGR ):    pFncGetPixel = GetPixelFor_24BIT_TC_BGR; break;
     348        2604 :                 case( BMP_FORMAT_24BIT_TC_RGB ):    pFncGetPixel = GetPixelFor_24BIT_TC_RGB; break;
     349           0 :                 case( BMP_FORMAT_24BIT_TC_MASK ):   pFncGetPixel = GetPixelFor_24BIT_TC_MASK; break;
     350           0 :                 case( BMP_FORMAT_32BIT_TC_ABGR ):   pFncGetPixel = GetPixelFor_32BIT_TC_ABGR; break;
     351           0 :                 case( BMP_FORMAT_32BIT_TC_ARGB ):   pFncGetPixel = GetPixelFor_32BIT_TC_ARGB; break;
     352           0 :                 case( BMP_FORMAT_32BIT_TC_BGRA ):   pFncGetPixel = GetPixelFor_32BIT_TC_BGRA; break;
     353           0 :                 case( BMP_FORMAT_32BIT_TC_RGBA ):   pFncGetPixel = GetPixelFor_32BIT_TC_RGBA; break;
     354           0 :                 case( BMP_FORMAT_32BIT_TC_MASK ):   pFncGetPixel = GetPixelFor_32BIT_TC_MASK; break;
     355             : 
     356             :                 default:
     357           0 :                     pFncGetPixel = NULL;
     358           0 :                 break;
     359             :             }
     360             : 
     361        2604 :             if( pFncGetPixel )
     362             :             {
     363        2604 :                 const ColorMask aDummyMask;
     364             : 
     365      103922 :                 for( long nX = 0L, nWidth = mpBuffer->mnWidth; nX < nWidth; nX++ )
     366      103922 :                     SetPixel( nY, nX, pFncGetPixel( aSrcScanline, nX, aDummyMask ) );
     367             :             }
     368             :         }
     369             :     }
     370       10501 : }
     371             : 
     372           0 : void BitmapWriteAccess::CopyBuffer( const BitmapReadAccess& rReadAcc )
     373             : {
     374             :     DBG_ASSERT( ( HasPalette() && rReadAcc.HasPalette() ) || ( !HasPalette() && !rReadAcc.HasPalette() ), "No copying possible between palette bitmap and TC bitmap!" );
     375             : 
     376           0 :     if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
     377           0 :         ( GetScanlineSize() == rReadAcc.GetScanlineSize() ) )
     378             :     {
     379           0 :         const long  nHeight = std::min( mpBuffer->mnHeight, rReadAcc.Height() );
     380           0 :         const sal_uLong nCount = nHeight * mpBuffer->mnScanlineSize;
     381             : 
     382           0 :         memcpy( mpBuffer->mpBits, rReadAcc.GetBuffer(), nCount );
     383             :     }
     384             :     else
     385           0 :         for( long nY = 0L, nHeight = std::min( mpBuffer->mnHeight, rReadAcc.Height() ); nY < nHeight; nY++ )
     386           0 :             CopyScanline( nY, rReadAcc );
     387         465 : }
     388             : 
     389             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10