LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/gdi - bmpacc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 107 180 59.4 %
Date: 2012-12-27 Functions: 13 15 86.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10