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