LCOV - code coverage report
Current view: top level - vcl/source/helper - canvasbitmap.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 317 726 43.7 %
Date: 2015-06-13 12:38:46 Functions: 21 39 53.8 %
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             : #include <com/sun/star/util/Endianness.hpp>
      21             : #include <com/sun/star/rendering/ColorComponentTag.hpp>
      22             : #include <com/sun/star/rendering/ColorSpaceType.hpp>
      23             : #include <com/sun/star/rendering/RenderingIntent.hpp>
      24             : 
      25             : #include <rtl/instance.hxx>
      26             : #include <osl/mutex.hxx>
      27             : 
      28             : #include <tools/diagnose_ex.h>
      29             : #include <canvasbitmap.hxx>
      30             : #include <vcl/canvastools.hxx>
      31             : #include <vcl/bmpacc.hxx>
      32             : #include <vcl/svapp.hxx>
      33             : 
      34             : #include <algorithm>
      35             : 
      36             : using namespace vcl::unotools;
      37             : using namespace ::com::sun::star;
      38             : 
      39             : namespace
      40             : {
      41             :     // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
      42             : 
      43             :     // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
      44             :     // unrolled loop. See e.g. Hackers Delight, p. 66
      45         936 :     inline sal_Int32 bitcount( sal_uInt32 val )
      46             :     {
      47         936 :         val = val - ((val >> 1) & 0x55555555);
      48         936 :         val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
      49         936 :         val = (val + (val >> 4)) & 0x0F0F0F0F;
      50         936 :         val = val + (val >> 8);
      51         936 :         val = val + (val >> 16);
      52         936 :         return sal_Int32(val & 0x0000003F);
      53             :     }
      54             : }
      55             : 
      56         312 : void VclCanvasBitmap::setComponentInfo( sal_uLong redShift, sal_uLong greenShift, sal_uLong blueShift )
      57             : {
      58             :     // sort channels in increasing order of appearance in the pixel
      59             :     // (starting with the least significant bits)
      60         312 :     sal_Int8 redPos(0);
      61         312 :     sal_Int8 greenPos(1);
      62         312 :     sal_Int8 bluePos(2);
      63             : 
      64         312 :     if( redShift > greenShift )
      65             :     {
      66         312 :         std::swap(redPos,greenPos);
      67         312 :         if( redShift > blueShift )
      68             :         {
      69         312 :             std::swap(redPos,bluePos);
      70         312 :             if( greenShift > blueShift )
      71         312 :                 std::swap(greenPos,bluePos);
      72             :         }
      73             :     }
      74             :     else
      75             :     {
      76           0 :         if( greenShift > blueShift )
      77             :         {
      78           0 :             std::swap(greenPos,bluePos);
      79           0 :             if( redShift > blueShift )
      80           0 :                 std::swap(redPos,bluePos);
      81             :         }
      82             :     }
      83             : 
      84         312 :     m_aComponentTags.realloc(3);
      85         312 :     sal_Int8* pTags = m_aComponentTags.getArray();
      86         312 :     pTags[redPos]   = rendering::ColorComponentTag::RGB_RED;
      87         312 :     pTags[greenPos] = rendering::ColorComponentTag::RGB_GREEN;
      88         312 :     pTags[bluePos]  = rendering::ColorComponentTag::RGB_BLUE;
      89             : 
      90         312 :     m_aComponentBitCounts.realloc(3);
      91         312 :     sal_Int32* pCounts = m_aComponentBitCounts.getArray();
      92         312 :     pCounts[redPos]    = bitcount(sal::static_int_cast<sal_uInt32>(redShift));
      93         312 :     pCounts[greenPos]  = bitcount(sal::static_int_cast<sal_uInt32>(greenShift));
      94         312 :     pCounts[bluePos]   = bitcount(sal::static_int_cast<sal_uInt32>(blueShift));
      95         312 : }
      96             : 
      97         326 : VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) :
      98             :     m_aBmpEx( rBitmap ),
      99             :     m_aBitmap( rBitmap.GetBitmap() ),
     100             :     m_aAlpha(),
     101         326 :     m_pBmpAcc( m_aBitmap.AcquireReadAccess() ),
     102             :     m_pAlphaAcc( NULL ),
     103             :     m_aComponentTags(),
     104             :     m_aComponentBitCounts(),
     105             :     m_aLayout(),
     106             :     m_nBitsPerInputPixel(0),
     107             :     m_nBitsPerOutputPixel(0),
     108             :     m_nRedIndex(-1),
     109             :     m_nGreenIndex(-1),
     110             :     m_nBlueIndex(-1),
     111             :     m_nAlphaIndex(-1),
     112             :     m_nIndexIndex(-1),
     113             :     m_nEndianness(0),
     114         652 :     m_bPalette(false)
     115             : {
     116         326 :     if( m_aBmpEx.IsTransparent() )
     117             :     {
     118         306 :         m_aAlpha = m_aBmpEx.IsAlpha() ? m_aBmpEx.GetAlpha().GetBitmap() : m_aBmpEx.GetMask();
     119         306 :         m_pAlphaAcc = m_aAlpha.AcquireReadAccess();
     120             :     }
     121             : 
     122         326 :     m_aLayout.ScanLines      = 0;
     123         326 :     m_aLayout.ScanLineBytes  = 0;
     124         326 :     m_aLayout.ScanLineStride = 0;
     125         326 :     m_aLayout.PlaneStride    = 0;
     126         326 :     m_aLayout.ColorSpace.clear();
     127         326 :     m_aLayout.Palette.clear();
     128         326 :     m_aLayout.IsMsbFirst     = false;
     129             : 
     130         326 :     if( m_pBmpAcc )
     131             :     {
     132         326 :         m_aLayout.ScanLines      = m_pBmpAcc->Height();
     133         326 :         m_aLayout.ScanLineBytes  = (m_pBmpAcc->GetBitCount()*m_pBmpAcc->Width() + 7) / 8;
     134         326 :         m_aLayout.ScanLineStride = m_pBmpAcc->GetScanlineSize();
     135         326 :         m_aLayout.PlaneStride    = 0;
     136             : 
     137         326 :         switch( m_pBmpAcc->GetScanlineFormat() )
     138             :         {
     139             :             case BMP_FORMAT_1BIT_MSB_PAL:
     140           4 :                 m_bPalette           = true;
     141           4 :                 m_nBitsPerInputPixel = 1;
     142           4 :                 m_nEndianness        = util::Endianness::LITTLE; // doesn't matter
     143           4 :                 m_aLayout.IsMsbFirst = true;
     144           4 :                 break;
     145             : 
     146             :             case BMP_FORMAT_1BIT_LSB_PAL:
     147           0 :                 m_bPalette           = true;
     148           0 :                 m_nBitsPerInputPixel = 1;
     149           0 :                 m_nEndianness        = util::Endianness::LITTLE; // doesn't matter
     150           0 :                 m_aLayout.IsMsbFirst = false;
     151           0 :                 break;
     152             : 
     153             :             case BMP_FORMAT_4BIT_MSN_PAL:
     154           4 :                 m_bPalette           = true;
     155           4 :                 m_nBitsPerInputPixel = 4;
     156           4 :                 m_nEndianness        = util::Endianness::LITTLE; // doesn't matter
     157           4 :                 m_aLayout.IsMsbFirst = true;
     158           4 :                 break;
     159             : 
     160             :             case BMP_FORMAT_4BIT_LSN_PAL:
     161           0 :                 m_bPalette           = true;
     162           0 :                 m_nBitsPerInputPixel = 4;
     163           0 :                 m_nEndianness        = util::Endianness::LITTLE; // doesn't matter
     164           0 :                 m_aLayout.IsMsbFirst = false;
     165           0 :                 break;
     166             : 
     167             :             case BMP_FORMAT_8BIT_PAL:
     168           6 :                 m_bPalette           = true;
     169           6 :                 m_nBitsPerInputPixel = 8;
     170           6 :                 m_nEndianness        = util::Endianness::LITTLE; // doesn't matter
     171           6 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     172           6 :                 break;
     173             : 
     174             :             case BMP_FORMAT_8BIT_TC_MASK:
     175           0 :                 m_bPalette           = false;
     176           0 :                 m_nBitsPerInputPixel = 8;
     177           0 :                 m_nEndianness        = util::Endianness::LITTLE; // doesn't matter
     178           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     179           0 :                 setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
     180           0 :                                   m_pBmpAcc->GetColorMask().GetGreenMask(),
     181           0 :                                   m_pBmpAcc->GetColorMask().GetBlueMask() );
     182           0 :                 break;
     183             : 
     184             :             case BMP_FORMAT_16BIT_TC_MSB_MASK:
     185           0 :                 m_bPalette           = false;
     186           0 :                 m_nBitsPerInputPixel = 16;
     187           0 :                 m_nEndianness        = util::Endianness::BIG;
     188           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     189           0 :                 setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
     190           0 :                                   m_pBmpAcc->GetColorMask().GetGreenMask(),
     191           0 :                                   m_pBmpAcc->GetColorMask().GetBlueMask() );
     192           0 :                 break;
     193             : 
     194             :             case BMP_FORMAT_16BIT_TC_LSB_MASK:
     195           3 :                 m_bPalette           = false;
     196           3 :                 m_nBitsPerInputPixel = 16;
     197           3 :                 m_nEndianness        = util::Endianness::LITTLE;
     198           3 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     199           3 :                 setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
     200           3 :                                   m_pBmpAcc->GetColorMask().GetGreenMask(),
     201           9 :                                   m_pBmpAcc->GetColorMask().GetBlueMask() );
     202           3 :                 break;
     203             : 
     204             :             case BMP_FORMAT_24BIT_TC_BGR:
     205           2 :                 m_bPalette           = false;
     206           2 :                 m_nBitsPerInputPixel = 24;
     207           2 :                 m_nEndianness        = util::Endianness::LITTLE;
     208           2 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     209             :                 setComponentInfo( 0xff0000LL,
     210             :                                   0x00ff00LL,
     211           2 :                                   0x0000ffLL );
     212           2 :                 break;
     213             : 
     214             :             case BMP_FORMAT_24BIT_TC_RGB:
     215           0 :                 m_bPalette           = false;
     216           0 :                 m_nBitsPerInputPixel = 24;
     217           0 :                 m_nEndianness        = util::Endianness::LITTLE;
     218           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     219             :                 setComponentInfo( 0x0000ffLL,
     220             :                                   0x00ff00LL,
     221           0 :                                   0xff0000LL );
     222           0 :                 break;
     223             : 
     224             :             case BMP_FORMAT_24BIT_TC_MASK:
     225           0 :                 m_bPalette           = false;
     226           0 :                 m_nBitsPerInputPixel = 24;
     227           0 :                 m_nEndianness        = util::Endianness::LITTLE;
     228           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     229           0 :                 setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
     230           0 :                                   m_pBmpAcc->GetColorMask().GetGreenMask(),
     231           0 :                                   m_pBmpAcc->GetColorMask().GetBlueMask() );
     232           0 :                 break;
     233             : 
     234             :             case BMP_FORMAT_32BIT_TC_ABGR:
     235             :             {
     236           0 :                 m_bPalette           = false;
     237           0 :                 m_nBitsPerInputPixel = 32;
     238           0 :                 m_nEndianness        = util::Endianness::LITTLE;
     239           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     240             : 
     241           0 :                 m_aComponentTags.realloc(4);
     242           0 :                 sal_Int8* pTags = m_aComponentTags.getArray();
     243           0 :                 pTags[0]        = rendering::ColorComponentTag::ALPHA;
     244           0 :                 pTags[1]        = rendering::ColorComponentTag::RGB_BLUE;
     245           0 :                 pTags[2]        = rendering::ColorComponentTag::RGB_GREEN;
     246           0 :                 pTags[3]        = rendering::ColorComponentTag::RGB_RED;
     247             : 
     248           0 :                 m_aComponentBitCounts.realloc(4);
     249           0 :                 sal_Int32* pCounts = m_aComponentBitCounts.getArray();
     250           0 :                 pCounts[0]         = 8;
     251           0 :                 pCounts[1]         = 8;
     252           0 :                 pCounts[2]         = 8;
     253           0 :                 pCounts[3]         = 8;
     254             : 
     255           0 :                 m_nRedIndex   = 3;
     256           0 :                 m_nGreenIndex = 2;
     257           0 :                 m_nBlueIndex  = 1;
     258           0 :                 m_nAlphaIndex = 0;
     259             :             }
     260           0 :             break;
     261             : 
     262             :             case BMP_FORMAT_32BIT_TC_ARGB:
     263             :             {
     264           0 :                 m_bPalette           = false;
     265           0 :                 m_nBitsPerInputPixel = 32;
     266           0 :                 m_nEndianness        = util::Endianness::LITTLE;
     267           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     268             : 
     269           0 :                 m_aComponentTags.realloc(4);
     270           0 :                 sal_Int8* pTags = m_aComponentTags.getArray();
     271           0 :                 pTags[0]        = rendering::ColorComponentTag::ALPHA;
     272           0 :                 pTags[1]        = rendering::ColorComponentTag::RGB_RED;
     273           0 :                 pTags[2]        = rendering::ColorComponentTag::RGB_GREEN;
     274           0 :                 pTags[3]        = rendering::ColorComponentTag::RGB_BLUE;
     275             : 
     276           0 :                 m_aComponentBitCounts.realloc(4);
     277           0 :                 sal_Int32* pCounts = m_aComponentBitCounts.getArray();
     278           0 :                 pCounts[0]         = 8;
     279           0 :                 pCounts[1]         = 8;
     280           0 :                 pCounts[2]         = 8;
     281           0 :                 pCounts[3]         = 8;
     282             : 
     283           0 :                 m_nRedIndex   = 1;
     284           0 :                 m_nGreenIndex = 2;
     285           0 :                 m_nBlueIndex  = 3;
     286           0 :                 m_nAlphaIndex = 0;
     287             :             }
     288           0 :             break;
     289             : 
     290             :             case BMP_FORMAT_32BIT_TC_BGRA:
     291             :             {
     292           0 :                 m_bPalette           = false;
     293           0 :                 m_nBitsPerInputPixel = 32;
     294           0 :                 m_nEndianness        = util::Endianness::LITTLE;
     295           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     296             : 
     297           0 :                 m_aComponentTags.realloc(4);
     298           0 :                 sal_Int8* pTags = m_aComponentTags.getArray();
     299           0 :                 pTags[0]        = rendering::ColorComponentTag::RGB_BLUE;
     300           0 :                 pTags[1]        = rendering::ColorComponentTag::RGB_GREEN;
     301           0 :                 pTags[2]        = rendering::ColorComponentTag::RGB_RED;
     302           0 :                 pTags[3]        = rendering::ColorComponentTag::ALPHA;
     303             : 
     304           0 :                 m_aComponentBitCounts.realloc(4);
     305           0 :                 sal_Int32* pCounts = m_aComponentBitCounts.getArray();
     306           0 :                 pCounts[0]         = 8;
     307           0 :                 pCounts[1]         = 8;
     308           0 :                 pCounts[2]         = 8;
     309           0 :                 pCounts[3]         = 8;
     310             : 
     311           0 :                 m_nRedIndex   = 2;
     312           0 :                 m_nGreenIndex = 1;
     313           0 :                 m_nBlueIndex  = 0;
     314           0 :                 m_nAlphaIndex = 3;
     315             :             }
     316           0 :             break;
     317             : 
     318             :             case BMP_FORMAT_32BIT_TC_RGBA:
     319             :             {
     320           0 :                 m_bPalette           = false;
     321           0 :                 m_nBitsPerInputPixel = 32;
     322           0 :                 m_nEndianness        = util::Endianness::LITTLE;
     323           0 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     324             : 
     325           0 :                 m_aComponentTags.realloc(4);
     326           0 :                 sal_Int8* pTags = m_aComponentTags.getArray();
     327           0 :                 pTags[0]        = rendering::ColorComponentTag::RGB_RED;
     328           0 :                 pTags[1]        = rendering::ColorComponentTag::RGB_GREEN;
     329           0 :                 pTags[2]        = rendering::ColorComponentTag::RGB_BLUE;
     330           0 :                 pTags[3]        = rendering::ColorComponentTag::ALPHA;
     331             : 
     332           0 :                 m_aComponentBitCounts.realloc(4);
     333           0 :                 sal_Int32* pCounts = m_aComponentBitCounts.getArray();
     334           0 :                 pCounts[0]         = 8;
     335           0 :                 pCounts[1]         = 8;
     336           0 :                 pCounts[2]         = 8;
     337           0 :                 pCounts[3]         = 8;
     338             : 
     339           0 :                 m_nRedIndex   = 0;
     340           0 :                 m_nGreenIndex = 1;
     341           0 :                 m_nBlueIndex  = 2;
     342           0 :                 m_nAlphaIndex = 3;
     343             :             }
     344           0 :             break;
     345             : 
     346             :             case BMP_FORMAT_32BIT_TC_MASK:
     347         307 :                 m_bPalette           = false;
     348         307 :                 m_nBitsPerInputPixel = 32;
     349         307 :                 m_nEndianness        = util::Endianness::LITTLE;
     350         307 :                 m_aLayout.IsMsbFirst = false; // doesn't matter
     351         307 :                 setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
     352         307 :                                   m_pBmpAcc->GetColorMask().GetGreenMask(),
     353         921 :                                   m_pBmpAcc->GetColorMask().GetBlueMask() );
     354         307 :                 break;
     355             : 
     356             :             default:
     357             :                 OSL_FAIL( "unsupported bitmap format" );
     358           0 :                 break;
     359             :         }
     360             : 
     361         326 :         if( m_bPalette )
     362             :         {
     363          14 :             m_aComponentTags.realloc(1);
     364          14 :             m_aComponentTags[0] = rendering::ColorComponentTag::INDEX;
     365             : 
     366          14 :             m_aComponentBitCounts.realloc(1);
     367          14 :             m_aComponentBitCounts[0] = m_nBitsPerInputPixel;
     368             : 
     369          14 :             m_nIndexIndex = 0;
     370             :         }
     371             : 
     372         326 :         m_nBitsPerOutputPixel = m_nBitsPerInputPixel;
     373         326 :         if( m_aBmpEx.IsTransparent() )
     374             :         {
     375             :             // TODO(P1): need to interleave alpha with bitmap data -
     376             :             // won't fuss with less-than-8 bit for now
     377         306 :             m_nBitsPerOutputPixel = std::max(sal_Int32(8),m_nBitsPerInputPixel);
     378             : 
     379             :             // check whether alpha goes in front or behind the
     380             :             // bitcount sequence. If pixel format is little endian,
     381             :             // put it behind all the other channels. If it's big
     382             :             // endian, put it in front (because later, the actual data
     383             :             // always gets written after the pixel data)
     384             : 
     385             :             // TODO(Q1): slight catch - in the case of the
     386             :             // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
     387             :             // channels might happen!
     388         306 :             m_aComponentTags.realloc(m_aComponentTags.getLength()+1);
     389         306 :             m_aComponentTags[m_aComponentTags.getLength()-1] = rendering::ColorComponentTag::ALPHA;
     390             : 
     391         306 :             m_aComponentBitCounts.realloc(m_aComponentBitCounts.getLength()+1);
     392         306 :             m_aComponentBitCounts[m_aComponentBitCounts.getLength()-1] = m_aBmpEx.IsAlpha() ? 8 : 1;
     393             : 
     394         306 :             if( m_nEndianness == util::Endianness::BIG )
     395             :             {
     396             :                 // put alpha in front of all the color channels
     397           0 :                 sal_Int8*  pTags  =m_aComponentTags.getArray();
     398           0 :                 sal_Int32* pCounts=m_aComponentBitCounts.getArray();
     399             :                 std::rotate(pTags,
     400           0 :                             pTags+m_aComponentTags.getLength()-1,
     401           0 :                             pTags+m_aComponentTags.getLength());
     402             :                 std::rotate(pCounts,
     403           0 :                             pCounts+m_aComponentBitCounts.getLength()-1,
     404           0 :                             pCounts+m_aComponentBitCounts.getLength());
     405           0 :                 ++m_nRedIndex;
     406           0 :                 ++m_nGreenIndex;
     407           0 :                 ++m_nBlueIndex;
     408           0 :                 ++m_nIndexIndex;
     409           0 :                 m_nAlphaIndex=0;
     410             :             }
     411             : 
     412             :             // always add a full byte to the pixel size, otherwise
     413             :             // pixel packing hell breaks loose.
     414         306 :             m_nBitsPerOutputPixel += 8;
     415             : 
     416             :             // adapt scanline parameters
     417         306 :             const Size aSize = m_aBitmap.GetSizePixel();
     418             :             m_aLayout.ScanLineBytes  =
     419         306 :             m_aLayout.ScanLineStride = (aSize.Width()*m_nBitsPerOutputPixel + 7)/8;
     420             :         }
     421             :     }
     422         326 : }
     423             : 
     424         978 : VclCanvasBitmap::~VclCanvasBitmap()
     425             : {
     426         326 :     if( m_pAlphaAcc )
     427         306 :         Bitmap::ReleaseAccess(m_pAlphaAcc);
     428         326 :     if( m_pBmpAcc )
     429         326 :         Bitmap::ReleaseAccess(m_pBmpAcc);
     430         652 : }
     431             : 
     432             : // XBitmap
     433          32 : geometry::IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() throw (uno::RuntimeException, std::exception)
     434             : {
     435          32 :     SolarMutexGuard aGuard;
     436          32 :     return integerSize2DFromSize( m_aBitmap.GetSizePixel() );
     437             : }
     438             : 
     439          17 : sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException, std::exception)
     440             : {
     441          17 :     SolarMutexGuard aGuard;
     442          17 :     return m_aBmpEx.IsTransparent();
     443             : }
     444             : 
     445          15 : uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D& newSize,
     446             :                                                                                 sal_Bool beFast ) throw (uno::RuntimeException, std::exception)
     447             : {
     448          15 :     SolarMutexGuard aGuard;
     449             : 
     450          30 :     BitmapEx aNewBmp( m_aBitmap );
     451          15 :     aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BmpScaleFlag::Default : BmpScaleFlag::BestQuality );
     452          30 :     return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) );
     453             : }
     454             : 
     455             : // XIntegerReadOnlyBitmap
     456          30 : uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerBitmapLayout&     bitmapLayout,
     457             :                                                              const geometry::IntegerRectangle2D& rect ) throw( lang::IndexOutOfBoundsException,
     458             :                                                                                                                rendering::VolatileContentDestroyedException,
     459             :                                                                                                                uno::RuntimeException, std::exception)
     460             : {
     461          30 :     SolarMutexGuard aGuard;
     462             : 
     463          30 :     bitmapLayout = getMemoryLayout();
     464             : 
     465          30 :     const ::Rectangle aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect) );
     466          30 :     if( aRequestedArea.IsEmpty() )
     467           0 :         return uno::Sequence< sal_Int8 >();
     468             : 
     469             :     // Invalid/empty bitmap: no data available
     470          30 :     if( !m_pBmpAcc )
     471           0 :         throw lang::IndexOutOfBoundsException();
     472          30 :     if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
     473           0 :         throw lang::IndexOutOfBoundsException();
     474             : 
     475         120 :     if( aRequestedArea.Left() < 0 || aRequestedArea.Top() < 0 ||
     476          90 :         aRequestedArea.Right() > m_pBmpAcc->Width() ||
     477          30 :         aRequestedArea.Bottom() > m_pBmpAcc->Height() )
     478             :     {
     479           0 :         throw lang::IndexOutOfBoundsException();
     480             :     }
     481             : 
     482          60 :     uno::Sequence< sal_Int8 > aRet;
     483          30 :     Rectangle aRequestedBytes( aRequestedArea );
     484             : 
     485             :     // adapt to byte boundaries
     486          30 :     aRequestedBytes.Left()  = aRequestedArea.Left()*m_nBitsPerOutputPixel/8;
     487          30 :     aRequestedBytes.Right() = (aRequestedArea.Right()*m_nBitsPerOutputPixel + 7)/8;
     488             : 
     489             :     // copy stuff to output sequence
     490          30 :     aRet.realloc(aRequestedBytes.getWidth()*aRequestedBytes.getHeight());
     491          30 :     sal_Int8* pOutBuf = aRet.getArray();
     492             : 
     493          30 :     bitmapLayout.ScanLines     = aRequestedBytes.getHeight();
     494             :     bitmapLayout.ScanLineBytes =
     495          30 :     bitmapLayout.ScanLineStride= aRequestedBytes.getWidth();
     496             : 
     497          30 :     sal_Int32 nScanlineStride=bitmapLayout.ScanLineStride;
     498          30 :     if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
     499             :     {
     500          30 :         pOutBuf += bitmapLayout.ScanLineStride*(aRequestedBytes.getHeight()-1);
     501          30 :         nScanlineStride *= -1;
     502             :     }
     503             : 
     504          30 :     if( !m_aBmpEx.IsTransparent() )
     505             :     {
     506             :         OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
     507             : 
     508             :         // can return bitmap data as-is
     509          20 :         for( long y=aRequestedBytes.Top(); y<aRequestedBytes.Bottom(); ++y )
     510             :         {
     511          10 :             Scanline pScan = m_pBmpAcc->GetScanline(y);
     512          10 :             memcpy(pOutBuf, pScan+aRequestedBytes.Left(), aRequestedBytes.getWidth());
     513          10 :             pOutBuf += nScanlineStride;
     514             :         }
     515             :     }
     516             :     else
     517             :     {
     518             :         OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
     519             :         OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
     520             : 
     521             :         // interleave alpha with bitmap data - note, bitcount is
     522             :         // always integer multiple of 8
     523             :         OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
     524             :                    "Transparent bitmap bitcount not integer multiple of 8" );
     525             : 
     526          40 :         for( long y=aRequestedArea.Top(); y<aRequestedArea.Bottom(); ++y )
     527             :         {
     528          20 :             sal_Int8* pOutScan = pOutBuf;
     529             : 
     530          20 :             if( m_nBitsPerInputPixel < 8 )
     531             :             {
     532             :                 // input less than a byte - copy via GetPixel()
     533         406 :                 for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
     534             :                 {
     535         402 :                     *pOutScan++ = m_pBmpAcc->GetPixelIndex(y,x);
     536         402 :                     *pOutScan++ = m_pAlphaAcc->GetPixelIndex(y,x);
     537             :                 }
     538             :             }
     539             :             else
     540             :             {
     541          16 :                 const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
     542          16 :                 const long nScanlineOffsetLeft(aRequestedArea.Left()*nNonAlphaBytes);
     543          16 :                 Scanline  pScan = m_pBmpAcc->GetScanline(y) + nScanlineOffsetLeft;
     544             : 
     545             :                 // input integer multiple of byte - copy directly
     546        1624 :                 for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
     547             :                 {
     548        6030 :                     for( long i=0; i<nNonAlphaBytes; ++i )
     549        4422 :                         *pOutScan++ = *pScan++;
     550        1608 :                     *pOutScan++ = m_pAlphaAcc->GetPixelIndex( y, x );
     551             :                 }
     552             :             }
     553             : 
     554          20 :             pOutBuf += nScanlineStride;
     555             :         }
     556             :     }
     557             : 
     558          60 :     return aRet;
     559             : }
     560             : 
     561          21 : uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout&   bitmapLayout,
     562             :                                                               const geometry::IntegerPoint2D&   pos ) throw (lang::IndexOutOfBoundsException,
     563             :                                                                                                              rendering::VolatileContentDestroyedException,
     564             :                                                                                                              uno::RuntimeException, std::exception)
     565             : {
     566          21 :     SolarMutexGuard aGuard;
     567             : 
     568          21 :     bitmapLayout = getMemoryLayout();
     569             : 
     570             :     // Invalid/empty bitmap: no data available
     571          21 :     if( !m_pBmpAcc )
     572           0 :         throw lang::IndexOutOfBoundsException();
     573          21 :     if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
     574           0 :         throw lang::IndexOutOfBoundsException();
     575             : 
     576          84 :     if( pos.X < 0 || pos.Y < 0 ||
     577          63 :         pos.X > m_pBmpAcc->Width() || pos.Y > m_pBmpAcc->Height() )
     578             :     {
     579           0 :         throw lang::IndexOutOfBoundsException();
     580             :     }
     581             : 
     582          21 :     uno::Sequence< sal_Int8 > aRet((m_nBitsPerOutputPixel + 7)/8);
     583          21 :     sal_Int8* pOutBuf = aRet.getArray();
     584             : 
     585             :     // copy stuff to output sequence
     586          21 :     bitmapLayout.ScanLines     = 1;
     587             :     bitmapLayout.ScanLineBytes =
     588          21 :     bitmapLayout.ScanLineStride= aRet.getLength();
     589             : 
     590          21 :     const long nScanlineLeftOffset( pos.X*m_nBitsPerInputPixel/8 );
     591          21 :     if( !m_aBmpEx.IsTransparent() )
     592             :     {
     593             :         assert(m_pBmpAcc && "Invalid bmp read access");
     594             : 
     595             :         // can return bitmap data as-is
     596           7 :         Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
     597           7 :         memcpy(pOutBuf, pScan+nScanlineLeftOffset, aRet.getLength() );
     598             :     }
     599             :     else
     600             :     {
     601             :         assert(m_pBmpAcc && "Invalid bmp read access");
     602             :         assert(m_pAlphaAcc && "Invalid alpha read access");
     603             : 
     604             :         // interleave alpha with bitmap data - note, bitcount is
     605             :         // always integer multiple of 8
     606             :         assert((m_nBitsPerOutputPixel & 0x07) == 0 &&
     607             :                    "Transparent bitmap bitcount not integer multiple of 8" );
     608             : 
     609          14 :         if( m_nBitsPerInputPixel < 8 )
     610             :         {
     611             :             // input less than a byte - copy via GetPixel()
     612           2 :             *pOutBuf++ = m_pBmpAcc->GetPixelIndex(pos.Y,pos.X);
     613           2 :             *pOutBuf   = m_pAlphaAcc->GetPixelIndex(pos.Y,pos.X);
     614             :         }
     615             :         else
     616             :         {
     617          12 :             const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
     618          12 :             Scanline  pScan = m_pBmpAcc->GetScanline(pos.Y);
     619             : 
     620             :             // input integer multiple of byte - copy directly
     621          12 :             memcpy(pOutBuf, pScan+nScanlineLeftOffset, nNonAlphaBytes );
     622          12 :             pOutBuf += nNonAlphaBytes;
     623          12 :             *pOutBuf++ = m_pAlphaAcc->GetPixelIndex(pos.Y,pos.X);
     624             :         }
     625             :     }
     626             : 
     627          21 :     return aRet;
     628             : }
     629             : 
     630           7 : uno::Reference< rendering::XBitmapPalette > SAL_CALL VclCanvasBitmap::getPalette() throw (uno::RuntimeException)
     631             : {
     632           7 :     SolarMutexGuard aGuard;
     633             : 
     634           7 :     uno::Reference< XBitmapPalette > aRet;
     635           7 :     if( m_bPalette )
     636           7 :         aRet.set(this);
     637             : 
     638           7 :     return aRet;
     639             : }
     640             : 
     641          51 : rendering::IntegerBitmapLayout SAL_CALL VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException, std::exception)
     642             : {
     643          51 :     SolarMutexGuard aGuard;
     644             : 
     645          51 :     rendering::IntegerBitmapLayout aLayout( m_aLayout );
     646             : 
     647             :     // only set references to self on separate copy of
     648             :     // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
     649             :     // a circular reference!
     650          51 :     if( m_bPalette )
     651          21 :         aLayout.Palette.set( this );
     652             : 
     653          51 :     aLayout.ColorSpace.set( this );
     654             : 
     655          51 :     return aLayout;
     656             : }
     657             : 
     658           7 : sal_Int32 SAL_CALL VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException, std::exception)
     659             : {
     660           7 :     SolarMutexGuard aGuard;
     661             : 
     662           7 :     if( !m_pBmpAcc )
     663           0 :         return 0;
     664             : 
     665           7 :     return m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ;
     666             : }
     667             : 
     668           7 : sal_Bool SAL_CALL VclCanvasBitmap::getIndex( uno::Sequence< double >& o_entry, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     669             : {
     670           7 :     SolarMutexGuard aGuard;
     671             : 
     672             :     const sal_uInt16 nCount( m_pBmpAcc ?
     673           7 :                          (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
     674             :     OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
     675           7 :     if( nIndex < 0 || nIndex >= nCount )
     676             :         throw lang::IndexOutOfBoundsException("Palette index out of range",
     677           0 :                                               static_cast<rendering::XBitmapPalette*>(this));
     678             : 
     679          14 :     const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(sal::static_int_cast<sal_uInt16>(nIndex));
     680           7 :     o_entry.realloc(3);
     681           7 :     double* pColor=o_entry.getArray();
     682           7 :     pColor[0] = aCol.GetRed();
     683           7 :     pColor[1] = aCol.GetGreen();
     684           7 :     pColor[2] = aCol.GetBlue();
     685             : 
     686          14 :     return sal_True; // no palette transparency here.
     687             : }
     688             : 
     689           7 : sal_Bool SAL_CALL VclCanvasBitmap::setIndex( const uno::Sequence< double >&, sal_Bool, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException, std::exception)
     690             : {
     691           7 :     SolarMutexGuard aGuard;
     692             : 
     693             :     const sal_uInt16 nCount( m_pBmpAcc ?
     694           7 :                          (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
     695             : 
     696             :     OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
     697           7 :     if( nIndex < 0 || nIndex >= nCount )
     698             :         throw lang::IndexOutOfBoundsException("Palette index out of range",
     699           0 :                                               static_cast<rendering::XBitmapPalette*>(this));
     700             : 
     701           7 :     return sal_False; // read-only implementation
     702             : }
     703             : 
     704             : namespace
     705             : {
     706             :     struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
     707             :                                                                PaletteColorSpaceHolder>
     708             :     {
     709           1 :         uno::Reference<rendering::XColorSpace> operator()()
     710             :         {
     711           1 :             return vcl::unotools::createStandardColorSpace();
     712             :         }
     713             :     };
     714             : }
     715             : 
     716           7 : uno::Reference< rendering::XColorSpace > SAL_CALL VclCanvasBitmap::getColorSpace(  ) throw (uno::RuntimeException, std::exception)
     717             : {
     718             :     // this is the method from XBitmapPalette. Return palette color
     719             :     // space here
     720           7 :     return PaletteColorSpaceHolder::get();
     721             : }
     722             : 
     723           0 : sal_Int8 SAL_CALL VclCanvasBitmap::getType(  ) throw (uno::RuntimeException, std::exception)
     724             : {
     725           0 :     return rendering::ColorSpaceType::RGB;
     726             : }
     727             : 
     728           0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::getComponentTags(  ) throw (uno::RuntimeException, std::exception)
     729             : {
     730           0 :     SolarMutexGuard aGuard;
     731           0 :     return m_aComponentTags;
     732             : }
     733             : 
     734           0 : sal_Int8 SAL_CALL VclCanvasBitmap::getRenderingIntent(  ) throw (uno::RuntimeException, std::exception)
     735             : {
     736           0 :     return rendering::RenderingIntent::PERCEPTUAL;
     737             : }
     738             : 
     739           0 : uno::Sequence< ::beans::PropertyValue > SAL_CALL VclCanvasBitmap::getProperties(  ) throw (uno::RuntimeException, std::exception)
     740             : {
     741           0 :     return uno::Sequence< ::beans::PropertyValue >();
     742             : }
     743             : 
     744           0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertColorSpace( const uno::Sequence< double >& deviceColor,
     745             :                                                                      const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (uno::RuntimeException, std::exception)
     746             : {
     747             :     // TODO(P3): if we know anything about target
     748             :     // colorspace, this can be greatly sped up
     749             :     uno::Sequence<rendering::ARGBColor> aIntermediate(
     750           0 :         convertToARGB(deviceColor));
     751           0 :     return targetColorSpace->convertFromARGB(aIntermediate);
     752             : }
     753             : 
     754           0 : uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
     755             : {
     756           0 :     SolarMutexGuard aGuard;
     757             : 
     758           0 :     const sal_Size  nLen( deviceColor.getLength() );
     759           0 :     const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
     760           0 :     ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
     761             :                          "number of channels no multiple of pixel element count",
     762             :                          static_cast<rendering::XBitmapPalette*>(this), 01);
     763             : 
     764           0 :     uno::Sequence< rendering::RGBColor > aRes(nLen/nComponentsPerPixel);
     765           0 :     rendering::RGBColor* pOut( aRes.getArray() );
     766             : 
     767           0 :     if( m_bPalette )
     768             :     {
     769             :         OSL_ENSURE(m_nIndexIndex != -1,
     770             :                    "Invalid color channel indices");
     771           0 :         ENSURE_OR_THROW(m_pBmpAcc,
     772             :                         "Unable to get BitmapAccess");
     773             : 
     774           0 :         for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
     775             :         {
     776             :             const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
     777           0 :                 sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
     778             : 
     779             :             // TODO(F3): Convert result to sRGB color space
     780           0 :             *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
     781           0 :                                           toDoubleColor(aCol.GetGreen()),
     782           0 :                                           toDoubleColor(aCol.GetBlue()));
     783           0 :         }
     784             :     }
     785             :     else
     786             :     {
     787             :         OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
     788             :                    "Invalid color channel indices");
     789             : 
     790           0 :         for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
     791             :         {
     792             :             // TODO(F3): Convert result to sRGB color space
     793             :             *pOut++ = rendering::RGBColor(
     794           0 :                 deviceColor[i+m_nRedIndex],
     795           0 :                 deviceColor[i+m_nGreenIndex],
     796           0 :                 deviceColor[i+m_nBlueIndex]);
     797             :         }
     798             :     }
     799             : 
     800           0 :     return aRes;
     801             : }
     802             : 
     803           0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
     804             : {
     805           0 :     SolarMutexGuard aGuard;
     806             : 
     807           0 :     const sal_Size  nLen( deviceColor.getLength() );
     808           0 :     const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
     809           0 :     ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
     810             :                          "number of channels no multiple of pixel element count",
     811             :                          static_cast<rendering::XBitmapPalette*>(this), 01);
     812             : 
     813           0 :     uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
     814           0 :     rendering::ARGBColor* pOut( aRes.getArray() );
     815             : 
     816           0 :     if( m_bPalette )
     817             :     {
     818             :         OSL_ENSURE(m_nIndexIndex != -1,
     819             :                    "Invalid color channel indices");
     820           0 :         ENSURE_OR_THROW(m_pBmpAcc,
     821             :                         "Unable to get BitmapAccess");
     822             : 
     823           0 :         for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
     824             :         {
     825             :             const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
     826           0 :                 sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
     827             : 
     828             :             // TODO(F3): Convert result to sRGB color space
     829           0 :             const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
     830             :             *pOut++ = rendering::ARGBColor(nAlpha,
     831           0 :                                            toDoubleColor(aCol.GetRed()),
     832           0 :                                            toDoubleColor(aCol.GetGreen()),
     833           0 :                                            toDoubleColor(aCol.GetBlue()));
     834           0 :         }
     835             :     }
     836             :     else
     837             :     {
     838             :         OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
     839             :                    "Invalid color channel indices");
     840             : 
     841           0 :         for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
     842             :         {
     843             :             // TODO(F3): Convert result to sRGB color space
     844           0 :             const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
     845             :             *pOut++ = rendering::ARGBColor(
     846             :                 nAlpha,
     847           0 :                 deviceColor[i+m_nRedIndex],
     848           0 :                 deviceColor[i+m_nGreenIndex],
     849           0 :                 deviceColor[i+m_nBlueIndex]);
     850             :         }
     851             :     }
     852             : 
     853           0 :     return aRes;
     854             : }
     855             : 
     856           0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
     857             : {
     858           0 :     SolarMutexGuard aGuard;
     859             : 
     860           0 :     const sal_Size  nLen( deviceColor.getLength() );
     861           0 :     const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
     862           0 :     ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
     863             :                          "number of channels no multiple of pixel element count",
     864             :                          static_cast<rendering::XBitmapPalette*>(this), 01);
     865             : 
     866           0 :     uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
     867           0 :     rendering::ARGBColor* pOut( aRes.getArray() );
     868             : 
     869           0 :     if( m_bPalette )
     870             :     {
     871             :         OSL_ENSURE(m_nIndexIndex != -1,
     872             :                    "Invalid color channel indices");
     873           0 :         ENSURE_OR_THROW(m_pBmpAcc,
     874             :                         "Unable to get BitmapAccess");
     875             : 
     876           0 :         for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
     877             :         {
     878             :             const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
     879           0 :                 sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
     880             : 
     881             :             // TODO(F3): Convert result to sRGB color space
     882           0 :             const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
     883             :             *pOut++ = rendering::ARGBColor(nAlpha,
     884           0 :                                            nAlpha*toDoubleColor(aCol.GetRed()),
     885           0 :                                            nAlpha*toDoubleColor(aCol.GetGreen()),
     886           0 :                                            nAlpha*toDoubleColor(aCol.GetBlue()));
     887           0 :         }
     888             :     }
     889             :     else
     890             :     {
     891             :         OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
     892             :                    "Invalid color channel indices");
     893             : 
     894           0 :         for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
     895             :         {
     896             :             // TODO(F3): Convert result to sRGB color space
     897           0 :             const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
     898             :             *pOut++ = rendering::ARGBColor(
     899             :                 nAlpha,
     900           0 :                 nAlpha*deviceColor[i+m_nRedIndex],
     901           0 :                 nAlpha*deviceColor[i+m_nGreenIndex],
     902           0 :                 nAlpha*deviceColor[i+m_nBlueIndex]);
     903             :         }
     904             :     }
     905             : 
     906           0 :     return aRes;
     907             : }
     908             : 
     909           0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
     910             : {
     911           0 :     SolarMutexGuard aGuard;
     912             : 
     913           0 :     const sal_Size  nLen( rgbColor.getLength() );
     914           0 :     const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
     915             : 
     916           0 :     uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
     917           0 :     double* pColors=aRes.getArray();
     918             : 
     919           0 :     if( m_bPalette )
     920             :     {
     921           0 :         for( sal_Size i=0; i<nLen; ++i )
     922             :         {
     923           0 :             pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
     924           0 :                     BitmapColor(toByteColor(rgbColor[i].Red),
     925           0 :                                 toByteColor(rgbColor[i].Green),
     926           0 :                                 toByteColor(rgbColor[i].Blue)));
     927           0 :             if( m_nAlphaIndex != -1 )
     928           0 :                 pColors[m_nAlphaIndex] = 1.0;
     929             : 
     930           0 :             pColors += nComponentsPerPixel;
     931             :         }
     932             :     }
     933             :     else
     934             :     {
     935           0 :         for( sal_Size i=0; i<nLen; ++i )
     936             :         {
     937           0 :             pColors[m_nRedIndex]   = rgbColor[i].Red;
     938           0 :             pColors[m_nGreenIndex] = rgbColor[i].Green;
     939           0 :             pColors[m_nBlueIndex]  = rgbColor[i].Blue;
     940           0 :             if( m_nAlphaIndex != -1 )
     941           0 :                 pColors[m_nAlphaIndex] = 1.0;
     942             : 
     943           0 :             pColors += nComponentsPerPixel;
     944             :         }
     945             :     }
     946           0 :     return aRes;
     947             : }
     948             : 
     949           0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
     950             : {
     951           0 :     SolarMutexGuard aGuard;
     952             : 
     953           0 :     const sal_Size  nLen( rgbColor.getLength() );
     954           0 :     const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
     955             : 
     956           0 :     uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
     957           0 :     double* pColors=aRes.getArray();
     958             : 
     959           0 :     if( m_bPalette )
     960             :     {
     961           0 :         for( sal_Size i=0; i<nLen; ++i )
     962             :         {
     963           0 :             pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
     964           0 :                     BitmapColor(toByteColor(rgbColor[i].Red),
     965           0 :                                 toByteColor(rgbColor[i].Green),
     966           0 :                                 toByteColor(rgbColor[i].Blue)));
     967           0 :             if( m_nAlphaIndex != -1 )
     968           0 :                 pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
     969             : 
     970           0 :             pColors += nComponentsPerPixel;
     971             :         }
     972             :     }
     973             :     else
     974             :     {
     975           0 :         for( sal_Size i=0; i<nLen; ++i )
     976             :         {
     977           0 :             pColors[m_nRedIndex]   = rgbColor[i].Red;
     978           0 :             pColors[m_nGreenIndex] = rgbColor[i].Green;
     979           0 :             pColors[m_nBlueIndex]  = rgbColor[i].Blue;
     980           0 :             if( m_nAlphaIndex != -1 )
     981           0 :                 pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
     982             : 
     983           0 :             pColors += nComponentsPerPixel;
     984             :         }
     985             :     }
     986           0 :     return aRes;
     987             : }
     988             : 
     989           0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
     990             : {
     991           0 :     SolarMutexGuard aGuard;
     992             : 
     993           0 :     const sal_Size  nLen( rgbColor.getLength() );
     994           0 :     const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
     995             : 
     996           0 :     uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
     997           0 :     double* pColors=aRes.getArray();
     998             : 
     999           0 :     if( m_bPalette )
    1000             :     {
    1001           0 :         for( sal_Size i=0; i<nLen; ++i )
    1002             :         {
    1003           0 :             const double nAlpha( rgbColor[i].Alpha );
    1004           0 :             pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
    1005           0 :                     BitmapColor(toByteColor(rgbColor[i].Red / nAlpha),
    1006           0 :                                 toByteColor(rgbColor[i].Green / nAlpha),
    1007           0 :                                 toByteColor(rgbColor[i].Blue / nAlpha)));
    1008           0 :             if( m_nAlphaIndex != -1 )
    1009           0 :                 pColors[m_nAlphaIndex] = nAlpha;
    1010             : 
    1011           0 :             pColors += nComponentsPerPixel;
    1012             :         }
    1013             :     }
    1014             :     else
    1015             :     {
    1016           0 :         for( sal_Size i=0; i<nLen; ++i )
    1017             :         {
    1018           0 :             const double nAlpha( rgbColor[i].Alpha );
    1019           0 :             pColors[m_nRedIndex]   = rgbColor[i].Red / nAlpha;
    1020           0 :             pColors[m_nGreenIndex] = rgbColor[i].Green / nAlpha;
    1021           0 :             pColors[m_nBlueIndex]  = rgbColor[i].Blue / nAlpha;
    1022           0 :             if( m_nAlphaIndex != -1 )
    1023           0 :                 pColors[m_nAlphaIndex] = nAlpha;
    1024             : 
    1025           0 :             pColors += nComponentsPerPixel;
    1026             :         }
    1027             :     }
    1028           0 :     return aRes;
    1029             : }
    1030             : 
    1031           0 : sal_Int32 SAL_CALL VclCanvasBitmap::getBitsPerPixel(  ) throw (uno::RuntimeException, std::exception)
    1032             : {
    1033           0 :     SolarMutexGuard aGuard;
    1034           0 :     return m_nBitsPerOutputPixel;
    1035             : }
    1036             : 
    1037           0 : uno::Sequence< ::sal_Int32 > SAL_CALL VclCanvasBitmap::getComponentBitCounts(  ) throw (uno::RuntimeException, std::exception)
    1038             : {
    1039           0 :     SolarMutexGuard aGuard;
    1040           0 :     return m_aComponentBitCounts;
    1041             : }
    1042             : 
    1043           0 : sal_Int8 SAL_CALL VclCanvasBitmap::getEndianness(  ) throw (uno::RuntimeException, std::exception)
    1044             : {
    1045           0 :     SolarMutexGuard aGuard;
    1046           0 :     return m_nEndianness;
    1047             : }
    1048             : 
    1049           0 : uno::Sequence<double> SAL_CALL VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
    1050             :                                                                               const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1051             : {
    1052           0 :     if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
    1053             :     {
    1054           0 :         SolarMutexGuard aGuard;
    1055             : 
    1056           0 :         const sal_Size  nLen( deviceColor.getLength() );
    1057           0 :         const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
    1058           0 :         ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
    1059             :                              "number of channels no multiple of pixel element count",
    1060             :                              static_cast<rendering::XBitmapPalette*>(this), 01);
    1061             : 
    1062           0 :         uno::Sequence<double> aRes(nLen);
    1063           0 :         double* pOut( aRes.getArray() );
    1064             : 
    1065           0 :         if( m_bPalette )
    1066             :         {
    1067             :             OSL_ENSURE(m_nIndexIndex != -1,
    1068             :                        "Invalid color channel indices");
    1069           0 :             ENSURE_OR_THROW(m_pBmpAcc,
    1070             :                             "Unable to get BitmapAccess");
    1071             : 
    1072           0 :             for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
    1073             :             {
    1074             :                 const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
    1075           0 :                     sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
    1076             : 
    1077             :                 // TODO(F3): Convert result to sRGB color space
    1078           0 :                 const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
    1079           0 :                 *pOut++ = toDoubleColor(aCol.GetRed());
    1080           0 :                 *pOut++ = toDoubleColor(aCol.GetGreen());
    1081           0 :                 *pOut++ = toDoubleColor(aCol.GetBlue());
    1082           0 :                 *pOut++ = nAlpha;
    1083           0 :             }
    1084             :         }
    1085             :         else
    1086             :         {
    1087             :             OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
    1088             :                        "Invalid color channel indices");
    1089             : 
    1090           0 :             for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
    1091             :             {
    1092             :                 // TODO(F3): Convert result to sRGB color space
    1093           0 :                 const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
    1094           0 :                 *pOut++ = deviceColor[i+m_nRedIndex];
    1095           0 :                 *pOut++ = deviceColor[i+m_nGreenIndex];
    1096           0 :                 *pOut++ = deviceColor[i+m_nBlueIndex];
    1097           0 :                 *pOut++ = nAlpha;
    1098             :             }
    1099             :         }
    1100             : 
    1101           0 :         return aRes;
    1102             :     }
    1103             :     else
    1104             :     {
    1105             :         // TODO(P3): if we know anything about target
    1106             :         // colorspace, this can be greatly sped up
    1107             :         uno::Sequence<rendering::ARGBColor> aIntermediate(
    1108           0 :             convertIntegerToARGB(deviceColor));
    1109           0 :         return targetColorSpace->convertFromARGB(aIntermediate);
    1110             :     }
    1111             : }
    1112             : 
    1113           0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
    1114             :                                                                                   const uno::Reference< ::rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1115             : {
    1116           0 :     if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
    1117             :     {
    1118             :         // it's us, so simply pass-through the data
    1119           0 :         return deviceColor;
    1120             :     }
    1121             :     else
    1122             :     {
    1123             :         // TODO(P3): if we know anything about target
    1124             :         // colorspace, this can be greatly sped up
    1125             :         uno::Sequence<rendering::ARGBColor> aIntermediate(
    1126           0 :             convertIntegerToARGB(deviceColor));
    1127           0 :         return targetColorSpace->convertIntegerFromARGB(aIntermediate);
    1128             :     }
    1129             : }
    1130             : 
    1131          15 : uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1132             : {
    1133          15 :     SolarMutexGuard aGuard;
    1134             : 
    1135          15 :     const sal_uInt8*     pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
    1136          15 :     const sal_Size  nLen( deviceColor.getLength() );
    1137          15 :     const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
    1138             : 
    1139          15 :     uno::Sequence< rendering::RGBColor > aRes(nNumColors);
    1140          15 :     rendering::RGBColor* pOut( aRes.getArray() );
    1141             : 
    1142          15 :     ENSURE_OR_THROW(m_pBmpAcc,
    1143             :                     "Unable to get BitmapAccess");
    1144             : 
    1145          15 :     if( m_aBmpEx.IsTransparent() )
    1146             :     {
    1147          10 :         const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
    1148        2010 :         for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
    1149             :         {
    1150             :             // if palette, index is guaranteed to be 8 bit
    1151             :             const BitmapColor aCol =
    1152             :                 m_bPalette ?
    1153         800 :                 m_pBmpAcc->GetPaletteColor(*pIn) :
    1154        2800 :                 m_pBmpAcc->GetPixelFromData(pIn,0);
    1155             : 
    1156             :             // TODO(F3): Convert result to sRGB color space
    1157        2000 :             *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
    1158        2000 :                                           toDoubleColor(aCol.GetGreen()),
    1159        6000 :                                           toDoubleColor(aCol.GetBlue()));
    1160             :             // skips alpha
    1161        2000 :             pIn += nBytesPerPixel;
    1162        2000 :         }
    1163             :     }
    1164             :     else
    1165             :     {
    1166        1005 :         for( sal_Int32 i=0; i<nNumColors; ++i )
    1167             :         {
    1168             :             const BitmapColor aCol =
    1169             :                 m_bPalette ?
    1170        2800 :                 m_pBmpAcc->GetPaletteColor( m_pBmpAcc->GetPixelFromData( pIn, i ).GetIndex()) :
    1171        2600 :                 m_pBmpAcc->GetPixelFromData(pIn, i);
    1172             : 
    1173             :             // TODO(F3): Convert result to sRGB color space
    1174        1000 :             *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
    1175        1000 :                                           toDoubleColor(aCol.GetGreen()),
    1176        3000 :                                           toDoubleColor(aCol.GetBlue()));
    1177        1000 :         }
    1178             :     }
    1179             : 
    1180          15 :     return aRes;
    1181             : }
    1182             : 
    1183          15 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1184             : {
    1185          15 :     SolarMutexGuard aGuard;
    1186             : 
    1187          15 :     const sal_uInt8*     pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
    1188          15 :     const sal_Size  nLen( deviceColor.getLength() );
    1189          15 :     const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
    1190             : 
    1191          15 :     uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
    1192          15 :     rendering::ARGBColor* pOut( aRes.getArray() );
    1193             : 
    1194          15 :     ENSURE_OR_THROW(m_pBmpAcc,
    1195             :                     "Unable to get BitmapAccess");
    1196             : 
    1197          15 :     if( m_aBmpEx.IsTransparent() )
    1198             :     {
    1199          10 :         const long      nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
    1200          10 :         const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
    1201          10 :         const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
    1202        2010 :         for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
    1203             :         {
    1204             :             // if palette, index is guaranteed to be 8 bit
    1205             :             const BitmapColor aCol =
    1206             :                 m_bPalette ?
    1207         800 :                 m_pBmpAcc->GetPaletteColor(*pIn) :
    1208        2800 :                 m_pBmpAcc->GetPixelFromData(pIn,0);
    1209             : 
    1210             :             // TODO(F3): Convert result to sRGB color space
    1211        2000 :             *pOut++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]),
    1212        2000 :                                            toDoubleColor(aCol.GetRed()),
    1213        2000 :                                            toDoubleColor(aCol.GetGreen()),
    1214        8000 :                                            toDoubleColor(aCol.GetBlue()));
    1215        2000 :             pIn += nBytesPerPixel;
    1216        2000 :         }
    1217             :     }
    1218             :     else
    1219             :     {
    1220        1005 :         for( sal_Int32 i=0; i<nNumColors; ++i )
    1221             :         {
    1222             :             const BitmapColor aCol =
    1223             :                 m_bPalette ?
    1224        2800 :                 m_pBmpAcc->GetPaletteColor( m_pBmpAcc->GetPixelFromData( pIn, i ).GetIndex() ) :
    1225        2600 :                 m_pBmpAcc->GetPixelFromData(pIn, i);
    1226             : 
    1227             :             // TODO(F3): Convert result to sRGB color space
    1228             :             *pOut++ = rendering::ARGBColor(1.0,
    1229        1000 :                                            toDoubleColor(aCol.GetRed()),
    1230        1000 :                                            toDoubleColor(aCol.GetGreen()),
    1231        3000 :                                            toDoubleColor(aCol.GetBlue()));
    1232        1000 :         }
    1233             :     }
    1234             : 
    1235          15 :     return aRes;
    1236             : }
    1237             : 
    1238           0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1239             : {
    1240           0 :     SolarMutexGuard aGuard;
    1241             : 
    1242           0 :     const sal_uInt8*     pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
    1243           0 :     const sal_Size  nLen( deviceColor.getLength() );
    1244           0 :     const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
    1245             : 
    1246           0 :     uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
    1247           0 :     rendering::ARGBColor* pOut( aRes.getArray() );
    1248             : 
    1249           0 :     ENSURE_OR_THROW(m_pBmpAcc,
    1250             :                     "Unable to get BitmapAccess");
    1251             : 
    1252           0 :     if( m_aBmpEx.IsTransparent() )
    1253             :     {
    1254           0 :         const long      nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
    1255           0 :         const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
    1256           0 :         const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
    1257           0 :         for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
    1258             :         {
    1259             :             // if palette, index is guaranteed to be 8 bit
    1260             :             const BitmapColor aCol =
    1261             :                 m_bPalette ?
    1262           0 :                 m_pBmpAcc->GetPaletteColor(*pIn) :
    1263           0 :                 m_pBmpAcc->GetPixelFromData(pIn,0);
    1264             : 
    1265             :             // TODO(F3): Convert result to sRGB color space
    1266           0 :             const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]) );
    1267             :             *pOut++ = rendering::ARGBColor(nAlpha,
    1268           0 :                                            nAlpha*toDoubleColor(aCol.GetRed()),
    1269           0 :                                            nAlpha*toDoubleColor(aCol.GetGreen()),
    1270           0 :                                            nAlpha*toDoubleColor(aCol.GetBlue()));
    1271           0 :             pIn += nBytesPerPixel;
    1272           0 :         }
    1273             :     }
    1274             :     else
    1275             :     {
    1276           0 :         for( sal_Int32 i=0; i<nNumColors; ++i )
    1277             :         {
    1278             :             const BitmapColor aCol =
    1279             :                 m_bPalette ?
    1280           0 :                 m_pBmpAcc->GetPaletteColor( m_pBmpAcc->GetPixelFromData( pIn, i ).GetIndex() ) :
    1281           0 :                 m_pBmpAcc->GetPixelFromData(pIn, i);
    1282             : 
    1283             :             // TODO(F3): Convert result to sRGB color space
    1284             :             *pOut++ = rendering::ARGBColor(1.0,
    1285           0 :                                            toDoubleColor(aCol.GetRed()),
    1286           0 :                                            toDoubleColor(aCol.GetGreen()),
    1287           0 :                                            toDoubleColor(aCol.GetBlue()));
    1288           0 :         }
    1289             :     }
    1290             : 
    1291           0 :     return aRes;
    1292             : }
    1293             : 
    1294           2 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1295             : {
    1296           2 :     SolarMutexGuard aGuard;
    1297             : 
    1298           2 :     const sal_Size  nLen( rgbColor.getLength() );
    1299           2 :     const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
    1300             : 
    1301           2 :     uno::Sequence< sal_Int8 > aRes(nNumBytes);
    1302           2 :     sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
    1303             : 
    1304           2 :     if( m_aBmpEx.IsTransparent() )
    1305             :     {
    1306           0 :         const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
    1307           0 :         for( sal_Size i=0; i<nLen; ++i )
    1308             :         {
    1309           0 :             const BitmapColor aCol(toByteColor(rgbColor[i].Red),
    1310           0 :                                    toByteColor(rgbColor[i].Green),
    1311           0 :                                    toByteColor(rgbColor[i].Blue));
    1312             :             const BitmapColor aCol2 =
    1313             :                 m_bPalette ?
    1314             :                 BitmapColor(
    1315           0 :                     sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
    1316           0 :                 aCol;
    1317             : 
    1318           0 :             m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
    1319           0 :             pColors   += nNonAlphaBytes;
    1320           0 :             *pColors++ = sal_uInt8(255);
    1321           0 :         }
    1322             :     }
    1323             :     else
    1324             :     {
    1325           4 :         for( sal_Size i=0; i<nLen; ++i )
    1326             :         {
    1327           2 :             const BitmapColor aCol(toByteColor(rgbColor[i].Red),
    1328           2 :                                    toByteColor(rgbColor[i].Green),
    1329           6 :                                    toByteColor(rgbColor[i].Blue));
    1330             :             const BitmapColor aCol2 =
    1331             :                 m_bPalette ?
    1332             :                 BitmapColor(
    1333           0 :                     sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
    1334           4 :                 aCol;
    1335             : 
    1336           2 :             m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
    1337           2 :         }
    1338             :     }
    1339             : 
    1340           2 :     return aRes;
    1341             : }
    1342             : 
    1343           6 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1344             : {
    1345           6 :     SolarMutexGuard aGuard;
    1346             : 
    1347           6 :     const sal_Size  nLen( rgbColor.getLength() );
    1348           6 :     const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
    1349             : 
    1350           6 :     uno::Sequence< sal_Int8 > aRes(nNumBytes);
    1351           6 :     sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
    1352             : 
    1353           6 :     if( m_aBmpEx.IsTransparent() )
    1354             :     {
    1355           4 :         const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
    1356           8 :         for( sal_Size i=0; i<nLen; ++i )
    1357             :         {
    1358           4 :             const BitmapColor aCol(toByteColor(rgbColor[i].Red),
    1359           4 :                                    toByteColor(rgbColor[i].Green),
    1360          12 :                                    toByteColor(rgbColor[i].Blue));
    1361             :             const BitmapColor aCol2 =
    1362             :                 m_bPalette ?
    1363             :                 BitmapColor(
    1364           0 :                     sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
    1365           8 :                 aCol;
    1366             : 
    1367           4 :             m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
    1368           4 :             pColors   += nNonAlphaBytes;
    1369           4 :             *pColors++ = 255 - toByteColor(rgbColor[i].Alpha);
    1370           4 :         }
    1371             :     }
    1372             :     else
    1373             :     {
    1374           4 :         for( sal_Size i=0; i<nLen; ++i )
    1375             :         {
    1376           2 :             const BitmapColor aCol(toByteColor(rgbColor[i].Red),
    1377           2 :                                    toByteColor(rgbColor[i].Green),
    1378           6 :                                    toByteColor(rgbColor[i].Blue));
    1379             :             const BitmapColor aCol2 =
    1380             :                 m_bPalette ?
    1381             :                 BitmapColor(
    1382           0 :                     sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
    1383           4 :                 aCol;
    1384             : 
    1385           2 :             m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
    1386           2 :         }
    1387             :     }
    1388             : 
    1389           6 :     return aRes;
    1390             : }
    1391             : 
    1392           0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException, std::exception)
    1393             : {
    1394           0 :     SolarMutexGuard aGuard;
    1395             : 
    1396           0 :     const sal_Size  nLen( rgbColor.getLength() );
    1397           0 :     const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
    1398             : 
    1399           0 :     uno::Sequence< sal_Int8 > aRes(nNumBytes);
    1400           0 :     sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
    1401             : 
    1402           0 :     if( m_aBmpEx.IsTransparent() )
    1403             :     {
    1404           0 :         const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
    1405           0 :         for( sal_Size i=0; i<nLen; ++i )
    1406             :         {
    1407           0 :             const double nAlpha( rgbColor[i].Alpha );
    1408           0 :             const BitmapColor aCol(toByteColor(rgbColor[i].Red / nAlpha),
    1409           0 :                                    toByteColor(rgbColor[i].Green / nAlpha),
    1410           0 :                                    toByteColor(rgbColor[i].Blue / nAlpha));
    1411             :             const BitmapColor aCol2 =
    1412             :                 m_bPalette ?
    1413             :                 BitmapColor(
    1414           0 :                     sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
    1415           0 :                 aCol;
    1416             : 
    1417           0 :             m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
    1418           0 :             pColors   += nNonAlphaBytes;
    1419           0 :             *pColors++ = 255 - toByteColor(nAlpha);
    1420           0 :         }
    1421             :     }
    1422             :     else
    1423             :     {
    1424           0 :         for( sal_Size i=0; i<nLen; ++i )
    1425             :         {
    1426           0 :             const BitmapColor aCol(toByteColor(rgbColor[i].Red),
    1427           0 :                                    toByteColor(rgbColor[i].Green),
    1428           0 :                                    toByteColor(rgbColor[i].Blue));
    1429             :             const BitmapColor aCol2 =
    1430             :                 m_bPalette ?
    1431             :                 BitmapColor(
    1432           0 :                     sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
    1433           0 :                 aCol;
    1434             : 
    1435           0 :             m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
    1436           0 :         }
    1437             :     }
    1438             : 
    1439           0 :     return aRes;
    1440             : }
    1441             : 
    1442             : 
    1443             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11