LCOV - code coverage report
Current view: top level - vcl/qa/cppunit - canvasbitmaptest.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 330 404 81.7 %
Date: 2015-06-13 12:38:46 Functions: 32 52 61.5 %
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             : // bootstrap stuff
      21             : #include <test/bootstrapfixture.hxx>
      22             : 
      23             : #include <com/sun/star/util/Endianness.hpp>
      24             : #include <com/sun/star/rendering/ColorComponentTag.hpp>
      25             : #include <com/sun/star/rendering/ColorSpaceType.hpp>
      26             : #include <com/sun/star/rendering/RenderingIntent.hpp>
      27             : #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
      28             : #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
      29             : #include <com/sun/star/rendering/XBitmapPalette.hpp>
      30             : 
      31             : #include <cppuhelper/compbase3.hxx>
      32             : #include <tools/diagnose_ex.h>
      33             : #include <rtl/ref.hxx>
      34             : 
      35             : #include "vcl/svapp.hxx"
      36             : #include "vcl/canvastools.hxx"
      37             : #include "vcl/dialog.hxx"
      38             : #include "vcl/outdev.hxx"
      39             : #include "vcl/bmpacc.hxx"
      40             : #include "vcl/virdev.hxx"
      41             : #include "vcl/bitmapex.hxx"
      42             : 
      43             : #include "canvasbitmap.hxx"
      44             : #include <algorithm>
      45             : 
      46             : using namespace ::com::sun::star;
      47             : using namespace vcl::unotools;
      48             : 
      49             : namespace com { namespace sun { namespace star { namespace rendering
      50             : {
      51             : 
      52        3000 : bool operator==( const RGBColor& rLHS, const ARGBColor& rRHS )
      53             : {
      54        3000 :     return rLHS.Red == rRHS.Red && rLHS.Green == rRHS.Green && rLHS.Blue == rRHS.Blue;
      55             : }
      56             : 
      57             : } } } }
      58             : 
      59             : namespace
      60             : {
      61             : 
      62           2 : class CanvasBitmapTest : public test::BootstrapFixture
      63             : {
      64             : public:
      65           1 :     CanvasBitmapTest() : BootstrapFixture(true, false) {}
      66             : 
      67             :     void runTest();
      68             : 
      69           2 :     CPPUNIT_TEST_SUITE(CanvasBitmapTest);
      70           1 :     CPPUNIT_TEST(runTest);
      71           5 :     CPPUNIT_TEST_SUITE_END();
      72             : };
      73             : 
      74        3000 : bool rangeCheck( const rendering::RGBColor& rColor )
      75             : {
      76        9000 :     return rColor.Red < 0.0 || rColor.Red > 1.0 ||
      77        9000 :         rColor.Green < 0.0 || rColor.Green > 1.0 ||
      78        9000 :         rColor.Blue < 0.0 || rColor.Blue > 1.0;
      79             : }
      80             : 
      81          15 : void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp,
      82             :                         const char*                            msg,
      83             :                         int                                    nOriginalDepth )
      84             : {
      85             :     OSL_TRACE("-------------------------");
      86             :     OSL_TRACE("Testing %s, with depth %d", msg, nOriginalDepth);
      87             : 
      88          15 :     BitmapEx aContainedBmpEx( xBmp->getBitmapEx() );
      89          30 :     Bitmap   aContainedBmp( aContainedBmpEx.GetBitmap() );
      90          15 :     int      nDepth = nOriginalDepth;
      91             : 
      92             :     {
      93          15 :         Bitmap::ScopedReadAccess pAcc( aContainedBmp );
      94          15 :         nDepth = pAcc->GetBitCount();
      95             :     }
      96             : 
      97          30 :     CPPUNIT_ASSERT_MESSAGE( "Original bitmap size not (200,200)",
      98          15 :                             aContainedBmp.GetSizePixel() == Size(200,200));
      99             : 
     100          30 :     CPPUNIT_ASSERT_MESSAGE( "Original bitmap size via API not (200,200)",
     101          15 :                             xBmp->getSize().Width == 200 && xBmp->getSize().Height == 200);
     102             : 
     103          30 :     CPPUNIT_ASSERT_MESSAGE( "alpha state mismatch",
     104          15 :                             bool(xBmp->hasAlpha()) == aContainedBmpEx.IsTransparent());
     105             : 
     106          30 :     CPPUNIT_ASSERT_MESSAGE( "getScaledBitmap() failed",
     107          15 :                             xBmp->getScaledBitmap( geometry::RealSize2D(500,500), false ).is());
     108             : 
     109          30 :     rendering::IntegerBitmapLayout aLayout;
     110          30 :     uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1));
     111             : 
     112             :     const sal_Int32 nExpectedBitsPerPixel(
     113          15 :         aContainedBmpEx.IsTransparent() ? std::max(8,nDepth)+8 : nDepth);
     114          30 :     CPPUNIT_ASSERT_MESSAGE( "# scanlines not 1",
     115          15 :                             aLayout.ScanLines == 1);
     116          30 :     CPPUNIT_ASSERT_MESSAGE( "# scanline bytes mismatch",
     117          15 :                             aLayout.ScanLineBytes == (nExpectedBitsPerPixel+7)/8);
     118          30 :     CPPUNIT_ASSERT_MESSAGE( "# scanline stride mismatch",
     119             :                             aLayout.ScanLineStride == (nExpectedBitsPerPixel+7)/8 ||
     120          15 :                             aLayout.ScanLineStride == -(nExpectedBitsPerPixel+7)/8);
     121          30 :     CPPUNIT_ASSERT_MESSAGE( "# plane stride not 0",
     122          15 :                             aLayout.PlaneStride == 0);
     123             : 
     124          30 :     CPPUNIT_ASSERT_MESSAGE( "Color space not there",
     125          15 :                             aLayout.ColorSpace.is());
     126             : 
     127          30 :     CPPUNIT_ASSERT_MESSAGE( "Palette existence does not conform to bitmap",
     128          15 :                             aLayout.Palette.is() == (nDepth <= 8));
     129             : 
     130          30 :     uno::Sequence<sal_Int8> aPixelData2 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(0,0) );
     131             : 
     132          30 :     CPPUNIT_ASSERT_MESSAGE( "getData and getPixel did not return same amount of data",
     133          15 :                             aPixelData2.getLength() == aPixelData.getLength());
     134             : 
     135          15 :     aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1));
     136          30 :     CPPUNIT_ASSERT_MESSAGE( "# scanlines not 1 for getPixel",
     137          15 :                             aLayout.ScanLines == 1);
     138          30 :     CPPUNIT_ASSERT_MESSAGE( "# scanline bytes mismatch for getPixel",
     139          15 :                             aLayout.ScanLineBytes == (200*nExpectedBitsPerPixel+7)/8);
     140          30 :     CPPUNIT_ASSERT_MESSAGE( "# scanline stride mismatch for getPixel",
     141             :                             aLayout.ScanLineStride == (200*nExpectedBitsPerPixel+7)/8 ||
     142          15 :                             aLayout.ScanLineStride == -(200*nExpectedBitsPerPixel+7)/8);
     143             : 
     144          30 :     uno::Sequence< rendering::RGBColor >  aRGBColors  = xBmp->convertIntegerToRGB( aPixelData );
     145          30 :     uno::Sequence< rendering::ARGBColor > aARGBColors = xBmp->convertIntegerToARGB( aPixelData );
     146             : 
     147          15 :     const rendering::RGBColor*  pRGBStart ( aRGBColors.getConstArray() );
     148          15 :     const rendering::RGBColor*  pRGBEnd   ( aRGBColors.getConstArray()+aRGBColors.getLength() );
     149          15 :     const rendering::ARGBColor* pARGBStart( aARGBColors.getConstArray() );
     150             :     std::pair<const rendering::RGBColor*,
     151          15 :         const rendering::ARGBColor*> aRes = std::mismatch( pRGBStart, pRGBEnd, pARGBStart );
     152          30 :     CPPUNIT_ASSERT_MESSAGE( "argb and rgb colors are not equal",
     153          15 :                             aRes.first == pRGBEnd);
     154             : 
     155          30 :     CPPUNIT_ASSERT_MESSAGE( "rgb colors are not within [0,1] range",
     156          15 :                             std::none_of(pRGBStart,pRGBEnd,&rangeCheck));
     157             : 
     158          30 :     CPPUNIT_ASSERT_MESSAGE( "First pixel is not white",
     159          15 :                             pRGBStart[0].Red == 1.0 && pRGBStart[0].Green == 1.0 && pRGBStart[0].Blue == 1.0);
     160          30 :     CPPUNIT_ASSERT_MESSAGE( "Second pixel is not opaque",
     161          15 :                             pARGBStart[1].Alpha == 1.0);
     162          15 :     if( aContainedBmpEx.IsTransparent() )
     163             :     {
     164          20 :         CPPUNIT_ASSERT_MESSAGE( "First pixel is not fully transparent",
     165          10 :                                 pARGBStart[0].Alpha == 0.0);
     166             :     }
     167             : 
     168          30 :     CPPUNIT_ASSERT_MESSAGE( "Second pixel is not black",
     169          15 :                             pRGBStart[1].Red == 0.0 && pRGBStart[1].Green == 0.0 && pRGBStart[1].Blue == 0.0);
     170             : 
     171          15 :     if( nOriginalDepth > 8 )
     172             :     {
     173           6 :         const Color aCol(COL_GREEN);
     174          12 :         CPPUNIT_ASSERT_EQUAL_MESSAGE(
     175             :             "Sixth pixel is not green (red component)",
     176           6 :             vcl::unotools::toDoubleColor(aCol.GetRed()), pRGBStart[5].Red);
     177          12 :         CPPUNIT_ASSERT_EQUAL_MESSAGE(
     178             :             "Sixth pixel is not green (green component)",
     179           6 :             vcl::unotools::toDoubleColor(aCol.GetGreen()), pRGBStart[5].Green);
     180          12 :         CPPUNIT_ASSERT_EQUAL_MESSAGE(
     181             :             "Sixth pixel is not green (blue component)",
     182           6 :             vcl::unotools::toDoubleColor(aCol.GetBlue()), pRGBStart[5].Blue);
     183             :     }
     184           9 :     else if( nDepth <= 8 )
     185             :     {
     186           7 :         uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette();
     187          14 :         CPPUNIT_ASSERT_MESSAGE( "8bit or less: missing palette",
     188           7 :                                 xPal.is());
     189          14 :         CPPUNIT_ASSERT_MESSAGE( "Palette incorrect entry count",
     190           7 :                                 xPal->getNumberOfEntries() == 1L << nOriginalDepth);
     191          14 :         uno::Sequence<double> aIndex;
     192          14 :         CPPUNIT_ASSERT_MESSAGE( "Palette is not read-only",
     193           7 :                                 !xPal->setIndex(aIndex,true,0));
     194          14 :         CPPUNIT_ASSERT_MESSAGE( "Palette entry 0 is not opaque",
     195           7 :                                 xPal->getIndex(aIndex,0));
     196          14 :         CPPUNIT_ASSERT_MESSAGE( "Palette has no valid color space",
     197          14 :                                 xPal->getColorSpace().is());
     198             :     }
     199             : 
     200          30 :     CPPUNIT_ASSERT_MESSAGE( "150th pixel is not white",
     201             :                             pRGBStart[150].Red == 1.0 &&
     202             :                             pRGBStart[150].Green == 1.0 &&
     203          15 :                             pRGBStart[150].Blue == 1.0);
     204             : 
     205          15 :     if( nOriginalDepth > 8 )
     206             :     {
     207           6 :         uno::Sequence<rendering::ARGBColor> aARGBColor(1);
     208          12 :         uno::Sequence<rendering::RGBColor>  aRGBColor(1);
     209          12 :         uno::Sequence<sal_Int8> aPixel3, aPixel4;
     210             : 
     211           6 :         const Color aCol(COL_GREEN);
     212           6 :         aARGBColor[0].Red   = vcl::unotools::toDoubleColor(aCol.GetRed());
     213           6 :         aARGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen());
     214           6 :         aARGBColor[0].Blue  = vcl::unotools::toDoubleColor(aCol.GetBlue());
     215           6 :         aARGBColor[0].Alpha = 1.0;
     216             : 
     217           6 :         aRGBColor[0].Red   = vcl::unotools::toDoubleColor(aCol.GetRed());
     218           6 :         aRGBColor[0].Green = vcl::unotools::toDoubleColor(aCol.GetGreen());
     219           6 :         aRGBColor[0].Blue  = vcl::unotools::toDoubleColor(aCol.GetBlue());
     220             : 
     221           6 :         aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor );
     222           6 :         aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) );
     223          12 :         CPPUNIT_ASSERT_MESSAGE( "Green pixel from bitmap mismatch with manually converted green pixel",
     224           6 :                                 aPixel3 == aPixel4);
     225             : 
     226           6 :         if( !aContainedBmpEx.IsTransparent() )
     227             :         {
     228           2 :             aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor );
     229           4 :             CPPUNIT_ASSERT_MESSAGE( "Green pixel from bitmap mismatch with manually RGB-converted green pixel",
     230           2 :                                     aPixel3 == aPixel4);
     231           6 :         }
     232          15 :     }
     233          15 : }
     234             : 
     235           4 : class TestBitmap : public cppu::WeakImplHelper3< rendering::XIntegerReadOnlyBitmap,
     236             :                                                  rendering::XBitmapPalette,
     237             :                                                  rendering::XIntegerBitmapColorSpace >
     238             : {
     239             : private:
     240             :     geometry::IntegerSize2D        maSize;
     241             :     uno::Sequence<sal_Int8>        maComponentTags;
     242             :     uno::Sequence<sal_Int32>       maComponentBitCounts;
     243             :     rendering::IntegerBitmapLayout maLayout;
     244             :     const sal_Int32                mnBitsPerPixel;
     245             : 
     246             :     // XBitmap
     247           2 :     virtual geometry::IntegerSize2D SAL_CALL getSize() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE { return maSize; }
     248           2 :     virtual sal_Bool SAL_CALL hasAlpha(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE { return mnBitsPerPixel != 8; }
     249           0 :     virtual uno::Reference< rendering::XBitmap > SAL_CALL getScaledBitmap( const geometry::RealSize2D&,
     250           0 :                                                                            sal_Bool ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE { return this; }
     251             : 
     252             :     // XIntegerReadOnlyBitmap
     253          20 :     virtual uno::Sequence< ::sal_Int8 > SAL_CALL getData( rendering::IntegerBitmapLayout&     bitmapLayout,
     254             :                                                           const geometry::IntegerRectangle2D& rect )
     255             :         throw (lang::IndexOutOfBoundsException,
     256             :                rendering::VolatileContentDestroyedException,
     257             :                uno::RuntimeException,
     258             :                std::exception) SAL_OVERRIDE
     259             :     {
     260          20 :         CPPUNIT_ASSERT_MESSAGE( "X1 out of bounds", rect.X1 >= 0 );
     261          20 :         CPPUNIT_ASSERT_MESSAGE( "Y1 out of bounds", rect.Y1 >= 0 );
     262          20 :         CPPUNIT_ASSERT_MESSAGE( "X2 out of bounds", rect.X2 <= maSize.Width );
     263          20 :         CPPUNIT_ASSERT_MESSAGE( "Y2 out of bounds", rect.Y2 <= maSize.Height );
     264             : 
     265          20 :         bitmapLayout = getMemoryLayout();
     266             : 
     267          20 :         const sal_Int32 nWidth  = rect.X2-rect.X1;
     268          20 :         const sal_Int32 nHeight = rect.Y2-rect.Y1;
     269          20 :         const sal_Int32 nScanlineLen = (nWidth * mnBitsPerPixel + 7)/8;
     270          20 :         uno::Sequence<sal_Int8> aRes( nScanlineLen * nHeight );
     271          20 :         sal_Int8* pOut = aRes.getArray();
     272             : 
     273          20 :         bitmapLayout.ScanLines     = nHeight;
     274             :         bitmapLayout.ScanLineBytes =
     275          20 :         bitmapLayout.ScanLineStride= nScanlineLen;
     276             : 
     277          20 :         if( mnBitsPerPixel == 8 )
     278             :         {
     279          20 :             for( sal_Int32 y=0; y<nHeight; ++y )
     280             :             {
     281         110 :                 for( sal_Int32 x=0; x<nWidth; ++x )
     282         100 :                     pOut[ y*nScanlineLen + x ] = sal_Int8(x);
     283             :             }
     284             :         }
     285             :         else
     286             :         {
     287          20 :             for( sal_Int32 y=0; y<nHeight; ++y )
     288             :             {
     289         110 :                 for( sal_Int32 x=0; x<nWidth; ++x )
     290             :                 {
     291         100 :                     pOut[ y*nScanlineLen + 4*x     ] = sal_Int8(rect.X1);
     292         100 :                     pOut[ y*nScanlineLen + 4*x + 1 ] = sal_Int8(rect.Y2);
     293         100 :                     pOut[ y*nScanlineLen + 4*x + 2 ] = sal_Int8(x);
     294         100 :                     pOut[ y*nScanlineLen + 4*x + 3 ] = sal_Int8(rect.Y1);
     295             :                 }
     296             :             }
     297             :         }
     298             : 
     299          20 :         return aRes;
     300             :     }
     301             : 
     302           0 :     virtual uno::Sequence< ::sal_Int8 > SAL_CALL getPixel( rendering::IntegerBitmapLayout&,
     303             :                                                            const geometry::IntegerPoint2D&  )
     304             :         throw (lang::IndexOutOfBoundsException,
     305             :                rendering::VolatileContentDestroyedException,
     306             :                uno::RuntimeException,
     307             :                std::exception) SAL_OVERRIDE
     308             :     {
     309           0 :         CPPUNIT_ASSERT_MESSAGE("getPixel: method not implemented", false);
     310           0 :         return uno::Sequence< sal_Int8 >();
     311             :     }
     312             : 
     313         298 :     uno::Reference< rendering::XBitmapPalette > SAL_CALL getPalette(  ) throw (uno::RuntimeException)
     314             :     {
     315         298 :         uno::Reference< XBitmapPalette > aRet;
     316         298 :         if( mnBitsPerPixel == 8 )
     317         277 :             aRet.set(this);
     318         298 :         return aRet;
     319             :     }
     320             : 
     321          22 :     virtual rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     322             :     {
     323          22 :         rendering::IntegerBitmapLayout aLayout( maLayout );
     324             : 
     325          22 :         const sal_Int32 nScanlineLen = (maSize.Width * mnBitsPerPixel + 7)/8;
     326             : 
     327          22 :         aLayout.ScanLines     = maSize.Height;
     328             :         aLayout.ScanLineBytes =
     329          22 :         aLayout.ScanLineStride= nScanlineLen;
     330          22 :         aLayout.Palette = getPalette();
     331          22 :         aLayout.ColorSpace.set( this );
     332             : 
     333          22 :         return aLayout;
     334             :     }
     335             : 
     336             :     // XBitmapPalette
     337           1 :     virtual sal_Int32 SAL_CALL getNumberOfEntries() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     338             :     {
     339           2 :         CPPUNIT_ASSERT_MESSAGE( "Got palette getNumberOfEntries interface call without handing out palette",
     340           1 :                                 getPalette().is() );
     341             : 
     342           1 :         return 255;
     343             :     }
     344             : 
     345         255 :     virtual sal_Bool SAL_CALL getIndex( uno::Sequence< double >& entry,
     346             :                                           ::sal_Int32 nIndex )
     347             :         throw (lang::IndexOutOfBoundsException,
     348             :                uno::RuntimeException,
     349             :                std::exception) SAL_OVERRIDE
     350             :     {
     351         510 :         CPPUNIT_ASSERT_MESSAGE( "Got palette getIndex interface call without handing out palette",
     352         255 :                                 getPalette().is() );
     353         510 :         CPPUNIT_ASSERT_MESSAGE( "getIndex: index out of range",
     354         255 :                                 nIndex >= 0 && nIndex < 256 );
     355         510 :         entry = colorToStdColorSpaceSequence(
     356             :             Color(sal_uInt8(nIndex),
     357             :                   sal_uInt8(nIndex),
     358         255 :                   sal_uInt8(nIndex)) );
     359             : 
     360         255 :         return true; // no palette transparency here.
     361             :     }
     362             : 
     363           0 :     virtual sal_Bool SAL_CALL setIndex( const uno::Sequence< double >&,
     364             :                                           sal_Bool,
     365             :                                           ::sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException,
     366             :                                                                       lang::IllegalArgumentException,
     367             :                                                                       uno::RuntimeException,
     368             :                                                                       std::exception) SAL_OVERRIDE
     369             :     {
     370           0 :         CPPUNIT_ASSERT_MESSAGE( "Got palette setIndex interface call without handing out palette",
     371           0 :                                 getPalette().is());
     372           0 :         CPPUNIT_ASSERT_MESSAGE( "setIndex: index out of range",
     373           0 :                                 nIndex >= 0 && nIndex < 256);
     374           0 :         return false;
     375             :     }
     376             : 
     377             :     struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
     378             :                                                                PaletteColorSpaceHolder>
     379             :     {
     380           1 :         uno::Reference<rendering::XColorSpace> operator()()
     381             :         {
     382           1 :             return vcl::unotools::createStandardColorSpace();
     383             :         }
     384             :     };
     385             : 
     386           2 :     virtual uno::Reference< rendering::XColorSpace > SAL_CALL getColorSpace(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     387             :     {
     388             :         // this is the method from XBitmapPalette. Return palette color
     389             :         // space here
     390           2 :         return PaletteColorSpaceHolder::get();
     391             :     }
     392             : 
     393             :     // XIntegerBitmapColorSpace
     394           0 :     virtual ::sal_Int8 SAL_CALL getType(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     395             :     {
     396           0 :         return rendering::ColorSpaceType::RGB;
     397             :     }
     398             : 
     399           1 :     virtual uno::Sequence< sal_Int8 > SAL_CALL getComponentTags(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     400             :     {
     401           1 :         return maComponentTags;
     402             :     }
     403             : 
     404           0 :     virtual ::sal_Int8 SAL_CALL getRenderingIntent(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     405             :     {
     406           0 :         return rendering::RenderingIntent::PERCEPTUAL;
     407             :     }
     408             : 
     409           0 :     virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties()
     410             :         throw (uno::RuntimeException,
     411             :                std::exception) SAL_OVERRIDE
     412             :     {
     413           0 :         CPPUNIT_ASSERT_MESSAGE("getProperties: method not implemented", false );
     414           0 :         return uno::Sequence< ::beans::PropertyValue >();
     415             :     }
     416             : 
     417           0 :     virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >&,
     418             :                                                                 const uno::Reference< rendering::XColorSpace >& )
     419             :         throw (uno::RuntimeException,
     420             :                std::exception) SAL_OVERRIDE
     421             :     {
     422           0 :         CPPUNIT_ASSERT_MESSAGE("convertColorSpace: method not implemented", false);
     423           0 :         return uno::Sequence< double >();
     424             :     }
     425             : 
     426           0 :     virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& )
     427             :         throw (lang::IllegalArgumentException,
     428             :                uno::RuntimeException,
     429             :                std::exception) SAL_OVERRIDE
     430             :     {
     431           0 :         CPPUNIT_ASSERT_MESSAGE("convertToRGB: method not implemented", false);
     432           0 :         return uno::Sequence< rendering::RGBColor >();
     433             :     }
     434             : 
     435           0 :     virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& )
     436             :         throw (lang::IllegalArgumentException,
     437             :                uno::RuntimeException,
     438             :                std::exception) SAL_OVERRIDE
     439             :     {
     440           0 :         CPPUNIT_ASSERT_MESSAGE("convertToARGB: method not implemented", false);
     441           0 :         return uno::Sequence< rendering::ARGBColor >();
     442             :     }
     443             : 
     444           0 :     virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& )
     445             :         throw (lang::IllegalArgumentException,
     446             :                uno::RuntimeException,
     447             :                std::exception) SAL_OVERRIDE
     448             :     {
     449           0 :         CPPUNIT_ASSERT_MESSAGE("convertToPARGB: method not implemented", false);
     450           0 :         return uno::Sequence< rendering::ARGBColor >();
     451             :     }
     452             : 
     453           0 :     virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& )
     454             :         throw (lang::IllegalArgumentException,
     455             :                uno::RuntimeException,
     456             :                std::exception) SAL_OVERRIDE
     457             :     {
     458           0 :         CPPUNIT_ASSERT_MESSAGE("convertFromRGB: method not implemented", false);
     459           0 :         return uno::Sequence< double >();
     460             :     }
     461             : 
     462           0 :     virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& )
     463             :         throw (lang::IllegalArgumentException,
     464             :                uno::RuntimeException,
     465             :                std::exception) SAL_OVERRIDE
     466             :     {
     467           0 :         CPPUNIT_ASSERT_MESSAGE("convertFromARGB: this method is not expected to be called!", false);
     468           0 :         return uno::Sequence< double >();
     469             :     }
     470             : 
     471           0 :     virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& )
     472             :         throw (lang::IllegalArgumentException,
     473             :                uno::RuntimeException,
     474             :                std::exception) SAL_OVERRIDE
     475             :     {
     476           0 :         CPPUNIT_ASSERT_MESSAGE("convertFromPARGB: this method is not expected to be called!", false);
     477           0 :         return uno::Sequence< double >();
     478             :     }
     479             : 
     480           2 :     virtual ::sal_Int32 SAL_CALL getBitsPerPixel(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     481             :     {
     482           2 :         return mnBitsPerPixel;
     483             :     }
     484             : 
     485           1 :     virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     486             :     {
     487           1 :         return maComponentBitCounts;
     488             :     }
     489             : 
     490           0 :     virtual ::sal_Int8 SAL_CALL getEndianness(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     491             :     {
     492           0 :         return util::Endianness::LITTLE;
     493             :     }
     494             : 
     495           0 :     virtual uno::Sequence< double > SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& ,
     496             :                                                                            const uno::Reference< rendering::XColorSpace >& )
     497             :         throw (lang::IllegalArgumentException,
     498             :                uno::RuntimeException,
     499             :                std::exception) SAL_OVERRIDE
     500             :     {
     501           0 :         CPPUNIT_ASSERT_MESSAGE("convertFromIntegerColorSpace: method not implemented", false);
     502           0 :         return uno::Sequence< double >();
     503             :     }
     504             : 
     505           0 :     virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& ,
     506             :                                                                              const uno::Reference< rendering::XIntegerBitmapColorSpace >& )
     507             :         throw (lang::IllegalArgumentException,
     508             :                uno::RuntimeException,
     509             :                std::exception) SAL_OVERRIDE
     510             :     {
     511           0 :         CPPUNIT_ASSERT_MESSAGE("convertToIntegerColorSpace: method not implemented", false);
     512           0 :         return uno::Sequence< sal_Int8 >();
     513             :     }
     514             : 
     515          10 :     virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,
     516             :                                                                                                                                        uno::RuntimeException, std::exception) SAL_OVERRIDE
     517             :     {
     518          10 :         const uno::Sequence< rendering::ARGBColor > aTemp( convertIntegerToARGB(deviceColor) );
     519          10 :         const sal_Size nLen(aTemp.getLength());
     520          10 :         uno::Sequence< rendering::RGBColor > aRes( nLen );
     521          10 :         rendering::RGBColor* pOut = aRes.getArray();
     522         110 :         for( sal_Size i=0; i<nLen; ++i )
     523             :         {
     524         100 :             *pOut++ = rendering::RGBColor(aTemp[i].Red,
     525         100 :                                           aTemp[i].Green,
     526         300 :                                           aTemp[i].Blue);
     527             :         }
     528             : 
     529          10 :         return aRes;
     530             :     }
     531             : 
     532          20 :     virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,
     533             :                                                                                                                                          uno::RuntimeException, std::exception) SAL_OVERRIDE
     534             :     {
     535          20 :         const sal_Size  nLen( deviceColor.getLength() );
     536          20 :         const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4);
     537          40 :         CPPUNIT_ASSERT_MESSAGE("number of channels no multiple of pixel element count",
     538          20 :                                nLen%nBytesPerPixel==0);
     539             : 
     540          20 :         uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel );
     541          20 :         rendering::ARGBColor* pOut( aRes.getArray() );
     542             : 
     543          20 :         if( getPalette().is() )
     544             :         {
     545         110 :             for( sal_Size i=0; i<nLen; ++i )
     546             :             {
     547             :                 *pOut++ = rendering::ARGBColor(
     548             :                     1.0,
     549         100 :                     vcl::unotools::toDoubleColor(deviceColor[i]),
     550         100 :                     vcl::unotools::toDoubleColor(deviceColor[i]),
     551         300 :                     vcl::unotools::toDoubleColor(deviceColor[i]));
     552             :             }
     553             :         }
     554             :         else
     555             :         {
     556         110 :             for( sal_Size i=0; i<nLen; i+=4 )
     557             :             {
     558             :                 *pOut++ = rendering::ARGBColor(
     559         100 :                     vcl::unotools::toDoubleColor(deviceColor[i+3]),
     560         100 :                     vcl::unotools::toDoubleColor(deviceColor[i+0]),
     561         100 :                     vcl::unotools::toDoubleColor(deviceColor[i+1]),
     562         400 :                     vcl::unotools::toDoubleColor(deviceColor[i+2]));
     563             :             }
     564             :         }
     565             : 
     566          20 :         return aRes;
     567             :     }
     568             : 
     569           0 :     virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB(
     570             :         const uno::Sequence< ::sal_Int8 >& deviceColor)
     571             :             throw (lang::IllegalArgumentException,
     572             :                    uno::RuntimeException,
     573             :                    std::exception) SAL_OVERRIDE
     574             :     {
     575           0 :         const sal_Size  nLen( deviceColor.getLength() );
     576           0 :         const sal_Int32 nBytesPerPixel(mnBitsPerPixel == 8 ? 1 : 4);
     577           0 :         CPPUNIT_ASSERT_MESSAGE("number of channels no multiple of pixel element count",
     578           0 :                                nLen%nBytesPerPixel==0);
     579             : 
     580           0 :         uno::Sequence< rendering::ARGBColor > aRes( nLen / nBytesPerPixel );
     581           0 :         rendering::ARGBColor* pOut( aRes.getArray() );
     582             : 
     583           0 :         if( getPalette().is() )
     584             :         {
     585           0 :             for( sal_Size i=0; i<nLen; ++i )
     586             :             {
     587             :                 *pOut++ = rendering::ARGBColor(
     588             :                     1.0,
     589           0 :                     vcl::unotools::toDoubleColor(deviceColor[i]),
     590           0 :                     vcl::unotools::toDoubleColor(deviceColor[i]),
     591           0 :                     vcl::unotools::toDoubleColor(deviceColor[i]));
     592             :             }
     593             :         }
     594             :         else
     595             :         {
     596           0 :             for( sal_Size i=0; i<nLen; i+=4 )
     597             :             {
     598           0 :                 const double fAlpha=vcl::unotools::toDoubleColor(deviceColor[i+3]);
     599             :                 *pOut++ = rendering::ARGBColor(
     600             :                     fAlpha,
     601           0 :                     fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+0]),
     602           0 :                     fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+1]),
     603           0 :                     fAlpha*vcl::unotools::toDoubleColor(deviceColor[i+2]));
     604             :             }
     605             :         }
     606             : 
     607           0 :         return aRes;
     608             :     }
     609             : 
     610           0 :     virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB(
     611             :         const uno::Sequence< rendering::RGBColor >&)
     612             :             throw (lang::IllegalArgumentException,
     613             :                    uno::RuntimeException,
     614             :                    std::exception) SAL_OVERRIDE
     615             :     {
     616           0 :         CPPUNIT_ASSERT_MESSAGE("convertIntegerFromRGB: method not implemented", false);
     617           0 :         return uno::Sequence< sal_Int8 >();
     618             :     }
     619             : 
     620           0 :     virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& ) throw (lang::IllegalArgumentException,
     621             :                                                                                                                                uno::RuntimeException,
     622             :                                   std::exception) SAL_OVERRIDE
     623             :     {
     624           0 :         CPPUNIT_ASSERT_MESSAGE("convertIntegerFromARGB: method not implemented", false);
     625           0 :         return uno::Sequence< sal_Int8 >();
     626             :     }
     627             : 
     628           0 :     virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& )
     629             :         throw (lang::IllegalArgumentException,
     630             :         uno::RuntimeException,
     631             :         std::exception) SAL_OVERRIDE
     632             :     {
     633           0 :         CPPUNIT_ASSERT_MESSAGE("convertIntegerFromPARGB: method not implemented", false);
     634           0 :         return uno::Sequence< sal_Int8 >();
     635             :     }
     636             : 
     637             : public:
     638           2 :     TestBitmap( const geometry::IntegerSize2D& rSize, bool bPalette ) :
     639             :         maSize(rSize),
     640             :         maComponentTags(),
     641             :         maComponentBitCounts(),
     642             :         maLayout(),
     643           2 :         mnBitsPerPixel( bPalette ? 8 : 32 )
     644             :     {
     645           2 :         if( bPalette )
     646             :         {
     647           1 :             maComponentTags.realloc(1);
     648           1 :             maComponentTags[0] = rendering::ColorComponentTag::INDEX;
     649             : 
     650           1 :             maComponentBitCounts.realloc(1);
     651           1 :             maComponentBitCounts[0] = 8;
     652             :         }
     653             :         else
     654             :         {
     655           1 :             maComponentTags.realloc(4);
     656           1 :             sal_Int8* pTags = maComponentTags.getArray();
     657           1 :             pTags[0]        = rendering::ColorComponentTag::RGB_BLUE;
     658           1 :             pTags[1]        = rendering::ColorComponentTag::RGB_GREEN;
     659           1 :             pTags[2]        = rendering::ColorComponentTag::RGB_RED;
     660           1 :             pTags[3]        = rendering::ColorComponentTag::ALPHA;
     661             : 
     662           1 :             maComponentBitCounts.realloc(4);
     663           1 :             sal_Int32* pCounts = maComponentBitCounts.getArray();
     664           1 :             pCounts[0]         = 8;
     665           1 :             pCounts[1]         = 8;
     666           1 :             pCounts[2]         = 8;
     667           1 :             pCounts[3]         = 8;
     668             :         }
     669             : 
     670           2 :         maLayout.ScanLines      = 0;
     671           2 :         maLayout.ScanLineBytes  = 0;
     672           2 :         maLayout.ScanLineStride = 0;
     673           2 :         maLayout.PlaneStride    = 0;
     674           2 :         maLayout.ColorSpace.clear();
     675           2 :         maLayout.Palette.clear();
     676           2 :         maLayout.IsMsbFirst     = false;
     677           2 :     }
     678             : };
     679             : 
     680           1 : void CanvasBitmapTest::runTest()
     681             : {
     682             :     static const sal_Int8 lcl_depths[]={1,4,8,16,24};
     683             : 
     684             :     // Testing VclCanvasBitmap wrapper
     685             : 
     686           6 :     for( unsigned int i=0; i<SAL_N_ELEMENTS(lcl_depths); ++i )
     687             :     {
     688           5 :         const sal_Int8 nDepth( lcl_depths[i] );
     689           5 :         Bitmap aBitmap(Size(200,200),nDepth);
     690           5 :         aBitmap.Erase(COL_WHITE);
     691             :         {
     692           5 :             Bitmap::ScopedWriteAccess pAcc(aBitmap);
     693           5 :             if( pAcc.get() )
     694             :             {
     695           5 :                 BitmapColor aBlack(0);
     696          10 :                 BitmapColor aWhite(0);
     697           5 :                 if( pAcc->HasPalette() )
     698             :                 {
     699           3 :                     aBlack.SetIndex( sal::static_int_cast<sal_Int8>(pAcc->GetBestPaletteIndex(BitmapColor(0,0,0))) );
     700           3 :                     aWhite.SetIndex( sal::static_int_cast<sal_Int8>(pAcc->GetBestPaletteIndex(BitmapColor(255,255,255))) );
     701             :                 }
     702             :                 else
     703             :                 {
     704           2 :                     aBlack = Color(COL_BLACK);
     705           2 :                     aWhite = Color(COL_WHITE);
     706             :                 }
     707           5 :                 pAcc->SetFillColor(COL_GREEN);
     708           5 :                 pAcc->FillRect(Rectangle(0,0,100,100));
     709           5 :                 pAcc->SetPixel(0,0,aWhite);
     710           5 :                 pAcc->SetPixel(0,1,aBlack);
     711          10 :                 pAcc->SetPixel(0,2,aWhite);
     712           5 :             }
     713             :         }
     714             : 
     715          10 :         rtl::Reference<VclCanvasBitmap> xBmp( new VclCanvasBitmap(aBitmap) );
     716             : 
     717           5 :         checkCanvasBitmap( xBmp, "single bitmap", nDepth );
     718             : 
     719          10 :         Bitmap aMask(Size(200,200),1);
     720           5 :         aMask.Erase(COL_WHITE);
     721             :         {
     722           5 :             Bitmap::ScopedWriteAccess pAcc(aMask);
     723           5 :             if( pAcc.get() )
     724             :             {
     725           5 :                 pAcc->SetFillColor(COL_BLACK);
     726           5 :                 pAcc->FillRect(Rectangle(0,0,100,100));
     727           5 :                 pAcc->SetPixel(0,0,BitmapColor(1));
     728           5 :                 pAcc->SetPixel(0,1,BitmapColor(0));
     729           5 :                 pAcc->SetPixel(0,2,BitmapColor(1));
     730           5 :             }
     731             :         }
     732             : 
     733           5 :         xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aMask)) );
     734             : 
     735           5 :         checkCanvasBitmap( xBmp, "masked bitmap", nDepth );
     736             : 
     737          10 :         AlphaMask aAlpha(Size(200,200));
     738           5 :         aAlpha.Erase(255);
     739             :         {
     740           5 :             BitmapWriteAccess* pAcc = aAlpha.AcquireWriteAccess();
     741           5 :             if( pAcc )
     742             :             {
     743           5 :                 pAcc->SetFillColor(COL_BLACK);
     744           5 :                 pAcc->FillRect(Rectangle(0,0,100,100));
     745           5 :                 pAcc->SetPixel(0,0,BitmapColor(255));
     746           5 :                 pAcc->SetPixel(0,1,BitmapColor(0));
     747           5 :                 pAcc->SetPixel(0,2,BitmapColor(255));
     748           5 :                 aAlpha.ReleaseAccess(pAcc);
     749             :             }
     750             :         }
     751             : 
     752           5 :         xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aAlpha)) );
     753             : 
     754           5 :         checkCanvasBitmap( xBmp, "alpha bitmap", nDepth );
     755           5 :     }
     756             : 
     757             :     // Testing XBitmap import
     758             : 
     759             :     uno::Reference< rendering::XIntegerReadOnlyBitmap > xTestBmp(
     760           1 :         new TestBitmap( geometry::IntegerSize2D(10,10), true ));
     761             : 
     762           2 :     BitmapEx aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp);
     763           2 :     CPPUNIT_ASSERT_MESSAGE( "Palette bitmap is transparent",
     764           1 :                             !aBmp.IsTransparent());
     765           2 :     CPPUNIT_ASSERT_MESSAGE( "Bitmap does not have size (10,10)",
     766           1 :                             aBmp.GetSizePixel() == Size(10,10));
     767           2 :     CPPUNIT_ASSERT_MESSAGE( "Bitmap does not have bitcount of 8",
     768           1 :                             aBmp.GetBitCount() == 8);
     769             :     {
     770           1 :         BitmapReadAccess* pBmpAcc   = aBmp.GetBitmap().AcquireReadAccess();
     771             : 
     772           2 :         CPPUNIT_ASSERT_MESSAGE( "Bitmap has invalid BitmapReadAccess",
     773           1 :                                 pBmpAcc );
     774             : 
     775           2 :         CPPUNIT_ASSERT_MESSAGE("(0,0) incorrect content",
     776           1 :                                pBmpAcc->GetPixel(0,0) == BitmapColor(0));
     777           2 :         CPPUNIT_ASSERT_MESSAGE("(2,2) incorrect content",
     778           1 :                                pBmpAcc->GetPixel(2,2) == BitmapColor(2));
     779           2 :         CPPUNIT_ASSERT_MESSAGE("(9,2) incorrect content",
     780           1 :                                pBmpAcc->GetPixel(2,9) == BitmapColor(9));
     781             : 
     782           1 :         Bitmap::ReleaseAccess(pBmpAcc);
     783             :     }
     784             : 
     785           1 :     xTestBmp.set( new TestBitmap( geometry::IntegerSize2D(10,10), false ));
     786             : 
     787           1 :     aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp);
     788           2 :     CPPUNIT_ASSERT_MESSAGE( "Palette bitmap is not transparent",
     789           1 :                             aBmp.IsTransparent());
     790           2 :     CPPUNIT_ASSERT_MESSAGE( "Palette bitmap has no alpha",
     791           1 :                             aBmp.IsAlpha());
     792           2 :     CPPUNIT_ASSERT_MESSAGE( "Bitmap does not have size (10,10)",
     793           1 :                             aBmp.GetSizePixel() == Size(10,10));
     794           2 :     CPPUNIT_ASSERT_MESSAGE( "Bitmap has bitcount of 24",
     795           1 :                             aBmp.GetBitCount() == 24);
     796             :     {
     797           1 :         BitmapReadAccess* pBmpAcc   = aBmp.GetBitmap().AcquireReadAccess();
     798           1 :         BitmapReadAccess* pAlphaAcc = aBmp.GetAlpha().AcquireReadAccess();
     799             : 
     800           2 :         CPPUNIT_ASSERT_MESSAGE( "Bitmap has invalid BitmapReadAccess",
     801           1 :                                 pBmpAcc);
     802           2 :         CPPUNIT_ASSERT_MESSAGE( "Bitmap has invalid alpha BitmapReadAccess",
     803           1 :                                 pAlphaAcc);
     804             : 
     805           2 :         CPPUNIT_ASSERT_MESSAGE("(0,0) incorrect content",
     806           1 :                                pBmpAcc->GetPixel(0,0) == BitmapColor(0,1,0));
     807           2 :         CPPUNIT_ASSERT_MESSAGE("(0,0) incorrect alpha content",
     808           1 :                                pAlphaAcc->GetPixel(0,0) == BitmapColor(255));
     809           2 :         CPPUNIT_ASSERT_MESSAGE("(2,2) incorrect content",
     810           1 :                                pBmpAcc->GetPixel(2,2) == BitmapColor(0,3,2));
     811           2 :         CPPUNIT_ASSERT_MESSAGE("(2,2) incorrect alpha content",
     812           1 :                                pAlphaAcc->GetPixel(2,2) == BitmapColor(253));
     813           2 :         CPPUNIT_ASSERT_MESSAGE("(9,2) incorrect content",
     814           1 :                                pBmpAcc->GetPixel(2,9) == BitmapColor(0,3,9));
     815           2 :         CPPUNIT_ASSERT_MESSAGE("(9,2) correct alpha content",
     816           1 :                                pAlphaAcc->GetPixel(2,9) == BitmapColor(253));
     817             : 
     818           1 :         aBmp.GetAlpha().ReleaseAccess(pAlphaAcc);
     819           1 :         Bitmap::ReleaseAccess(pBmpAcc);
     820           1 :     }
     821           1 : }
     822             : 
     823             : } // namespace
     824             : 
     825           3 : CPPUNIT_TEST_SUITE_REGISTRATION(CanvasBitmapTest);
     826             : 
     827             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11