Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / vcl / headless / svpbmp.cxx
bloba310addb1ae0277d14534e523d7f027a127588e0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "headless/svpbmp.hxx"
22 #include <basegfx/vector/b2ivector.hxx>
23 #include <basegfx/range/b2ibox.hxx>
24 #include <basebmp/scanlineformats.hxx>
25 #include <basebmp/color.hxx>
27 #include <vcl/salbtype.hxx>
28 #include <vcl/bitmap.hxx>
30 using namespace basebmp;
31 using namespace basegfx;
33 SvpSalBitmap::~SvpSalBitmap()
37 bool SvpSalBitmap::Create( const Size& rSize,
38 sal_uInt16 nBitCount,
39 const BitmapPalette& rPalette )
41 basebmp::Format nFormat = SVP_DEFAULT_BITMAP_FORMAT;
42 SAL_INFO( "vcl.headless", "SvpSalBitmap::Create(" << rSize.Width() << "," << rSize.Height() << "," << nBitCount << ")" );
43 switch( nBitCount )
45 case 1: nFormat = FORMAT_ONE_BIT_MSB_PAL; break;
46 case 4: nFormat = FORMAT_FOUR_BIT_MSB_PAL; break;
47 case 8: nFormat = FORMAT_EIGHT_BIT_PAL; break;
48 #ifdef OSL_BIGENDIAN
49 case 16: nFormat = FORMAT_SIXTEEN_BIT_MSB_TC_MASK; break;
50 #else
51 case 16: nFormat = FORMAT_SIXTEEN_BIT_LSB_TC_MASK; break;
52 #endif
53 case 24: nFormat = FORMAT_TWENTYFOUR_BIT_TC_MASK; break;
54 #if defined(ANDROID) || defined(IOS)
55 case 32: nFormat = FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA; break;
56 #else
57 case 32: nFormat = FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA; break;
58 #endif
60 B2IVector aSize( rSize.Width(), rSize.Height() );
61 if( aSize.getX() == 0 )
62 aSize.setX( 1 );
63 if( aSize.getY() == 0 )
64 aSize.setY( 1 );
65 if( nBitCount > 8 )
66 m_aBitmap = createBitmapDevice( aSize, false, nFormat );
67 else
69 // prepare palette
70 unsigned int nEntries = 1U << nBitCount;
71 std::vector<basebmp::Color>* pPalette =
72 new std::vector<basebmp::Color>( nEntries, basebmp::Color(COL_WHITE) );
73 unsigned int nColors = rPalette.GetEntryCount();
74 for( unsigned int i = 0; i < nColors; i++ )
76 const BitmapColor& rCol = rPalette[i];
77 (*pPalette)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
79 m_aBitmap = createBitmapDevice( aSize, false, nFormat,
80 basebmp::RawMemorySharedArray(),
81 basebmp::PaletteMemorySharedVector( pPalette )
84 return true;
87 bool SvpSalBitmap::Create( const SalBitmap& rSalBmp )
89 const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBmp);
90 const BitmapDeviceSharedPtr& rSrcBmp = rSrc.getBitmap();
91 if( rSrcBmp.get() )
93 B2IVector aSize = rSrcBmp->getSize();
94 m_aBitmap = cloneBitmapDevice( aSize, rSrcBmp );
95 B2IBox aRect( 0, 0, aSize.getX(), aSize.getY() );
96 m_aBitmap->drawBitmap( rSrcBmp, aRect, aRect, DrawMode_PAINT );
98 else
99 m_aBitmap.reset();
101 return true;
104 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
105 SalGraphics* /*pGraphics*/ )
107 return false;
110 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
111 sal_uInt16 /*nNewBitCount*/ )
113 return false;
116 bool SvpSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
118 return false;
121 void SvpSalBitmap::Destroy()
123 m_aBitmap.reset();
126 Size SvpSalBitmap::GetSize() const
128 Size aSize;
129 if( m_aBitmap.get() )
131 B2IVector aVec( m_aBitmap->getSize() );
132 aSize = Size( aVec.getX(), aVec.getY() );
135 return aSize;
138 sal_uInt16 SvpSalBitmap::GetBitCount() const
140 sal_uInt16 nDepth = 0;
141 if( m_aBitmap.get() )
142 nDepth = getBitCountFromScanlineFormat( m_aBitmap->getScanlineFormat() );
143 return nDepth;
146 BitmapBuffer* SvpSalBitmap::AcquireBuffer( bool )
148 BitmapBuffer* pBuf = NULL;
149 if( m_aBitmap.get() )
151 pBuf = new BitmapBuffer();
152 sal_uInt16 nBitCount = 1;
153 switch( m_aBitmap->getScanlineFormat() )
155 case FORMAT_ONE_BIT_MSB_GREY:
156 case FORMAT_ONE_BIT_MSB_PAL:
157 nBitCount = 1;
158 pBuf->mnFormat = BMP_FORMAT_1BIT_MSB_PAL;
159 break;
160 case FORMAT_ONE_BIT_LSB_GREY:
161 case FORMAT_ONE_BIT_LSB_PAL:
162 nBitCount = 1;
163 pBuf->mnFormat = BMP_FORMAT_1BIT_LSB_PAL;
164 break;
165 case FORMAT_FOUR_BIT_MSB_GREY:
166 case FORMAT_FOUR_BIT_MSB_PAL:
167 nBitCount = 4;
168 pBuf->mnFormat = BMP_FORMAT_4BIT_MSN_PAL;
169 break;
170 case FORMAT_FOUR_BIT_LSB_GREY:
171 case FORMAT_FOUR_BIT_LSB_PAL:
172 nBitCount = 4;
173 pBuf->mnFormat = BMP_FORMAT_4BIT_LSN_PAL;
174 break;
175 case FORMAT_EIGHT_BIT_PAL:
176 nBitCount = 8;
177 pBuf->mnFormat = BMP_FORMAT_8BIT_PAL;
178 break;
179 case FORMAT_EIGHT_BIT_GREY:
180 nBitCount = 8;
181 pBuf->mnFormat = BMP_FORMAT_8BIT_PAL;
182 break;
183 case FORMAT_SIXTEEN_BIT_LSB_TC_MASK:
184 nBitCount = 16;
185 pBuf->mnFormat = BMP_FORMAT_16BIT_TC_LSB_MASK;
186 pBuf->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
187 break;
188 case FORMAT_SIXTEEN_BIT_MSB_TC_MASK:
189 nBitCount = 16;
190 pBuf->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
191 pBuf->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
192 break;
193 case FORMAT_TWENTYFOUR_BIT_TC_MASK:
194 nBitCount = 24;
195 pBuf->mnFormat = BMP_FORMAT_24BIT_TC_BGR;
196 break;
197 case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
198 nBitCount = 32;
199 pBuf->mnFormat = BMP_FORMAT_32BIT_TC_MASK;
200 #ifdef OSL_BIGENDIAN
201 pBuf->maColorMask = ColorMask( 0x0000ff00, 0x00ff0000, 0xff000000 );
202 #else
203 pBuf->maColorMask = ColorMask( 0x00ff0000, 0x0000ff00, 0x000000ff );
204 #endif
205 break;
206 case FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
207 nBitCount = 32;
208 pBuf->mnFormat = BMP_FORMAT_32BIT_TC_MASK;
209 #ifdef OSL_BIGENDIAN
210 pBuf->maColorMask = ColorMask( 0x00ff0000, 0x0000ff00, 0x000000ff );
211 #else
212 pBuf->maColorMask = ColorMask( 0x0000ff00, 0x00ff0000, 0xff000000 );
213 #endif
214 break;
215 case FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
216 nBitCount = 32;
217 pBuf->mnFormat = BMP_FORMAT_32BIT_TC_MASK;
218 #ifdef OSL_BIGENDIAN
219 pBuf->maColorMask = ColorMask( 0x000000ff, 0x0000ff00, 0x00ff0000 );
220 #else
221 pBuf->maColorMask = ColorMask( 0xff000000, 0x00ff0000, 0x0000ff00 );
222 #endif
223 break;
224 case FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
225 nBitCount = 32;
226 pBuf->mnFormat = BMP_FORMAT_32BIT_TC_MASK;
227 #ifdef OSL_BIGENDIAN
228 pBuf->maColorMask = ColorMask( 0xff000000, 0x00ff0000, 0x0000ff00 );
229 #else
230 pBuf->maColorMask = ColorMask( 0x000000ff, 0x0000ff00, 0x00ff0000 );
231 #endif
232 break;
234 default:
235 // this is an error case !!!!!
236 nBitCount = 1;
237 pBuf->mnFormat = BMP_FORMAT_1BIT_MSB_PAL;
238 break;
240 if( m_aBitmap->isTopDown() )
241 pBuf->mnFormat |= BMP_FORMAT_TOP_DOWN;
243 B2IVector aSize = m_aBitmap->getSize();
244 pBuf->mnWidth = aSize.getX();
245 pBuf->mnHeight = aSize.getY();
246 pBuf->mnScanlineSize = m_aBitmap->getScanlineStride();
247 pBuf->mnBitCount = nBitCount;
248 pBuf->mpBits = (sal_uInt8*)m_aBitmap->getBuffer().get();
249 if( nBitCount <= 8 )
251 if( m_aBitmap->getScanlineFormat() == FORMAT_EIGHT_BIT_GREY ||
252 m_aBitmap->getScanlineFormat() == FORMAT_FOUR_BIT_LSB_GREY ||
253 m_aBitmap->getScanlineFormat() == FORMAT_FOUR_BIT_MSB_GREY ||
254 m_aBitmap->getScanlineFormat() == FORMAT_ONE_BIT_LSB_GREY ||
255 m_aBitmap->getScanlineFormat() == FORMAT_ONE_BIT_MSB_GREY
257 pBuf->maPalette = Bitmap::GetGreyPalette( 1U << nBitCount );
258 else
260 basebmp::PaletteMemorySharedVector aPalette = m_aBitmap->getPalette();
261 if( aPalette.get() )
263 unsigned int nColors = aPalette->size();
264 if( nColors > 0 )
266 pBuf->maPalette.SetEntryCount( nColors );
267 for( unsigned int i = 0; i < nColors; i++ )
269 const basebmp::Color& rCol = (*aPalette)[i];
270 pBuf->maPalette[i] = BitmapColor( rCol.getRed(), rCol.getGreen(), rCol.getBlue() );
278 return pBuf;
281 void SvpSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
283 if( !bReadOnly && pBuffer->maPalette.GetEntryCount() )
285 // palette might have changed, clone device (but recycle
286 // memory)
287 sal_uInt16 nBitCount = 0;
288 switch( m_aBitmap->getScanlineFormat() )
290 case FORMAT_ONE_BIT_MSB_GREY:
291 // FALLTHROUGH intended
292 case FORMAT_ONE_BIT_MSB_PAL:
293 // FALLTHROUGH intended
294 case FORMAT_ONE_BIT_LSB_GREY:
295 // FALLTHROUGH intended
296 case FORMAT_ONE_BIT_LSB_PAL:
297 nBitCount = 1;
298 break;
300 case FORMAT_FOUR_BIT_MSB_GREY:
301 // FALLTHROUGH intended
302 case FORMAT_FOUR_BIT_MSB_PAL:
303 // FALLTHROUGH intended
304 case FORMAT_FOUR_BIT_LSB_GREY:
305 // FALLTHROUGH intended
306 case FORMAT_FOUR_BIT_LSB_PAL:
307 nBitCount = 4;
308 break;
310 case FORMAT_EIGHT_BIT_PAL:
311 // FALLTHROUGH intended
312 case FORMAT_EIGHT_BIT_GREY:
313 nBitCount = 8;
314 break;
316 default:
317 break;
320 if( nBitCount )
322 sal_uInt32 nEntries = 1U << nBitCount;
324 boost::shared_ptr< std::vector<basebmp::Color> > pPal(
325 new std::vector<basebmp::Color>( nEntries,
326 basebmp::Color(COL_WHITE)));
327 const sal_uInt32 nColors = std::min(
328 (sal_uInt32)pBuffer->maPalette.GetEntryCount(),
329 nEntries);
330 for( sal_uInt32 i = 0; i < nColors; i++ )
332 const BitmapColor& rCol = pBuffer->maPalette[i];
333 (*pPal)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() );
336 m_aBitmap = basebmp::createBitmapDevice( m_aBitmap->getSize(),
337 m_aBitmap->isTopDown(),
338 m_aBitmap->getScanlineFormat(),
339 m_aBitmap->getBuffer(),
340 pPal );
344 delete pBuffer;
347 bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
349 return false;
352 sal_uInt32 SvpSalBitmap::getBitCountFromScanlineFormat( basebmp::Format nFormat )
354 sal_uInt32 nBitCount = 1;
355 switch( nFormat )
357 case FORMAT_ONE_BIT_MSB_GREY:
358 case FORMAT_ONE_BIT_LSB_GREY:
359 case FORMAT_ONE_BIT_MSB_PAL:
360 case FORMAT_ONE_BIT_LSB_PAL:
361 nBitCount = 1;
362 break;
363 case FORMAT_FOUR_BIT_MSB_GREY:
364 case FORMAT_FOUR_BIT_LSB_GREY:
365 case FORMAT_FOUR_BIT_MSB_PAL:
366 case FORMAT_FOUR_BIT_LSB_PAL:
367 nBitCount = 4;
368 break;
369 case FORMAT_EIGHT_BIT_PAL:
370 case FORMAT_EIGHT_BIT_GREY:
371 nBitCount = 8;
372 break;
373 case FORMAT_SIXTEEN_BIT_LSB_TC_MASK:
374 case FORMAT_SIXTEEN_BIT_MSB_TC_MASK:
375 nBitCount = 16;
376 break;
377 case FORMAT_TWENTYFOUR_BIT_TC_MASK:
378 nBitCount = 24;
379 break;
380 case FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
381 case FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
382 case FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
383 case FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
384 nBitCount = 32;
385 break;
386 default:
387 OSL_FAIL( "unsupported basebmp format" );
388 break;
390 return nBitCount;
393 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */