xref: /aoo41x/main/vcl/source/helper/canvasbitmap.cxx (revision 37ab0f2d)
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
109f62ea84SAndrew Rist  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
129f62ea84SAndrew Rist  *
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.
199f62ea84SAndrew Rist  *
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
bitcount(sal_uInt32 val)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 
setComponentInfo(sal_uLong redShift,sal_uLong greenShift,sal_uLong blueShift)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 
VclCanvasBitmap(const BitmapEx & rBitmap)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 
~VclCanvasBitmap()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
getSize()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 
hasAlpha()448cdf0e10cSrcweir ::sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException)
449cdf0e10cSrcweir {
450cdf0e10cSrcweir     vos::OGuard aGuard( Application::GetSolarMutex() );
451cdf0e10cSrcweir     return m_aBmpEx.IsTransparent();
452cdf0e10cSrcweir }
453cdf0e10cSrcweir 
getScaledBitmap(const geometry::RealSize2D & newSize,sal_Bool beFast)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 );
460*37ab0f2dSArmin Le Grand     aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_FASTESTINTERPOLATE : BMP_SCALE_INTERPOLATE );
461cdf0e10cSrcweir     return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) );
462cdf0e10cSrcweir }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir // XIntegerReadOnlyBitmap
getData(rendering::IntegerBitmapLayout & bitmapLayout,const geometry::IntegerRectangle2D & rect)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                 {
54487bc88d3SHerbert Dürr                     *pOutScan++ = m_pBmpAcc->GetPixelIndex(y,x);
54587bc88d3SHerbert 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++;
55987bc88d3SHerbert Dürr                     *pOutScan++ = m_pAlphaAcc->GetPixelIndex( y, x );
560cdf0e10cSrcweir                 }
561cdf0e10cSrcweir             }
562cdf0e10cSrcweir 
563cdf0e10cSrcweir             pOutBuf += nScanlineStride;
564cdf0e10cSrcweir         }
565cdf0e10cSrcweir     }
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     return aRet;
568cdf0e10cSrcweir }
569cdf0e10cSrcweir 
getPixel(rendering::IntegerBitmapLayout & bitmapLayout,const geometry::IntegerPoint2D & pos)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()
62187bc88d3SHerbert Dürr             *pOutBuf++ = m_pBmpAcc->GetPixelIndex(pos.Y,pos.X);
62287bc88d3SHerbert 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;
63287bc88d3SHerbert Dürr             *pOutBuf++ = m_pAlphaAcc->GetPixelIndex(pos.Y,pos.X);
633cdf0e10cSrcweir         }
634cdf0e10cSrcweir     }
635cdf0e10cSrcweir 
636cdf0e10cSrcweir     return aRet;
637cdf0e10cSrcweir }
638cdf0e10cSrcweir 
getPalette()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 
getMemoryLayout()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 
getNumberOfEntries()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 
getIndex(uno::Sequence<double> & o_entry,sal_Int32 nIndex)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 
setIndex(const uno::Sequence<double> &,sal_Bool,sal_Int32 nIndex)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     {
operator ()__anon4b80e5d30211::PaletteColorSpaceHolder718cdf0e10cSrcweir         uno::Reference<rendering::XColorSpace> operator()()
719cdf0e10cSrcweir         {
720cdf0e10cSrcweir             return vcl::unotools::createStandardColorSpace();
721cdf0e10cSrcweir         }
722cdf0e10cSrcweir     };
723cdf0e10cSrcweir }
724cdf0e10cSrcweir 
getColorSpace()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 
getType()732cdf0e10cSrcweir sal_Int8 SAL_CALL VclCanvasBitmap::getType(  ) throw (uno::RuntimeException)
733cdf0e10cSrcweir {
734cdf0e10cSrcweir     return rendering::ColorSpaceType::RGB;
735cdf0e10cSrcweir }
736cdf0e10cSrcweir 
getComponentTags()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 
getRenderingIntent()743cdf0e10cSrcweir sal_Int8 SAL_CALL VclCanvasBitmap::getRenderingIntent(  ) throw (uno::RuntimeException)
744cdf0e10cSrcweir {
745cdf0e10cSrcweir     return rendering::RenderingIntent::PERCEPTUAL;
746cdf0e10cSrcweir }
747cdf0e10cSrcweir 
getProperties()748cdf0e10cSrcweir uno::Sequence< ::beans::PropertyValue > SAL_CALL VclCanvasBitmap::getProperties(  ) throw (uno::RuntimeException)
749cdf0e10cSrcweir {
750cdf0e10cSrcweir     return uno::Sequence< ::beans::PropertyValue >();
751cdf0e10cSrcweir }
752cdf0e10cSrcweir 
convertColorSpace(const uno::Sequence<double> & deviceColor,const uno::Reference<::rendering::XColorSpace> & targetColorSpace)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 
convertToRGB(const uno::Sequence<double> & deviceColor)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 
convertToARGB(const uno::Sequence<double> & deviceColor)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 
convertToPARGB(const uno::Sequence<double> & deviceColor)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 
convertFromRGB(const uno::Sequence<rendering::RGBColor> & rgbColor)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 
convertFromARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)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 
convertFromPARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)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 
getBitsPerPixel()1040cdf0e10cSrcweir sal_Int32 SAL_CALL VclCanvasBitmap::getBitsPerPixel(  ) throw (uno::RuntimeException)
1041cdf0e10cSrcweir {
1042cdf0e10cSrcweir     vos::OGuard aGuard( Application::GetSolarMutex() );
1043cdf0e10cSrcweir     return m_nBitsPerOutputPixel;
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir 
getComponentBitCounts()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 
getEndianness()1052cdf0e10cSrcweir sal_Int8 SAL_CALL VclCanvasBitmap::getEndianness(  ) throw (uno::RuntimeException)
1053cdf0e10cSrcweir {
1054cdf0e10cSrcweir     vos::OGuard aGuard( Application::GetSolarMutex() );
1055cdf0e10cSrcweir     return m_nEndianness;
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir 
convertFromIntegerColorSpace(const uno::Sequence<::sal_Int8> & deviceColor,const uno::Reference<::rendering::XColorSpace> & targetColorSpace)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 
convertToIntegerColorSpace(const uno::Sequence<::sal_Int8> & deviceColor,const uno::Reference<::rendering::XIntegerBitmapColorSpace> & targetColorSpace)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 
convertIntegerToRGB(const uno::Sequence<::sal_Int8> & deviceColor)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 ?
117987bc88d3SHerbert 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 
convertIntegerToARGB(const uno::Sequence<::sal_Int8> & deviceColor)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 ?
123387bc88d3SHerbert 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 
convertIntegerToPARGB(const uno::Sequence<::sal_Int8> & deviceColor)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 ?
128987bc88d3SHerbert 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 
convertIntegerFromRGB(const uno::Sequence<rendering::RGBColor> & rgbColor)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 
convertIntegerFromARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)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 
convertIntegerFromPARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)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 
getBitmapEx() const1451cdf0e10cSrcweir BitmapEx VclCanvasBitmap::getBitmapEx() const
1452cdf0e10cSrcweir {
1453cdf0e10cSrcweir     return m_aBmpEx;
1454cdf0e10cSrcweir }
1455