LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/helper - canvasbitmap.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 728 0.0 %
Date: 2012-12-27 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10