Bump version to 5.0-14
[LibreOffice.git] / filter / source / graphicfilter / expm / expm.cxx
blobfca1788fa1a747eb4a3dad6b2c09205819305fcf
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 .
21 #include <vcl/graph.hxx>
22 #include <vcl/bmpacc.hxx>
23 #include <vcl/fltcall.hxx>
25 //============================ XPMWriter ==================================
27 class XPMWriter {
29 private:
31 SvStream& m_rOStm; // the output XPM file
33 bool mbStatus;
34 bool mbTrans;
35 BitmapReadAccess* mpAcc;
36 sal_uLong mnWidth, mnHeight; // size in Pixel
37 sal_uInt16 mnColors;
39 com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
41 void ImplCallback( sal_uInt16 nPercent );
42 bool ImplWriteHeader();
43 void ImplWritePalette();
44 void ImplWriteColor( sal_uInt16 );
45 void ImplWriteBody();
46 void ImplWriteNumber( sal_Int32 );
47 void ImplWritePixel( sal_uLong ) const;
49 public:
50 XPMWriter(SvStream& rOStm);
51 ~XPMWriter();
53 bool WriteXPM( const Graphic& rGraphic, FilterConfigItem* pFilterConfigItem );
56 //=================== Methoden von XPMWriter ==============================
58 XPMWriter::XPMWriter(SvStream& rOStm)
59 : m_rOStm(rOStm)
60 , mbStatus(true)
61 , mbTrans(false)
62 , mpAcc(NULL)
63 , mnWidth(0)
64 , mnHeight(0)
65 , mnColors(0)
71 XPMWriter::~XPMWriter()
77 void XPMWriter::ImplCallback( sal_uInt16 nPercent )
79 if ( xStatusIndicator.is() )
81 if ( nPercent <= 100 )
82 xStatusIndicator->setValue( nPercent );
88 bool XPMWriter::WriteXPM( const Graphic& rGraphic, FilterConfigItem* pFilterConfigItem)
90 Bitmap aBmp;
92 if ( pFilterConfigItem )
94 xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
95 if ( xStatusIndicator.is() )
97 OUString aMsg;
98 xStatusIndicator->start( aMsg, 100 );
102 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
103 aBmp = aBmpEx.GetBitmap();
105 if ( rGraphic.IsTransparent() ) // possibly create transparent color
107 mbTrans = true;
108 if ( aBmp.GetBitCount() >= 8 ) // if necessary convert image to 8 bit
109 aBmp.Convert( BMP_CONVERSION_8BIT_TRANS );
110 else
111 aBmp.Convert( BMP_CONVERSION_4BIT_TRANS );
112 aBmp.Replace( aBmpEx.GetMask(), BMP_COL_TRANS );
114 else
116 if ( aBmp.GetBitCount() > 8 ) // if necessary convert image to 8 bit
117 aBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
119 mpAcc = aBmp.AcquireReadAccess();
120 if ( mpAcc )
122 SvStreamEndian nOStmOldModus = m_rOStm.GetEndian();
123 m_rOStm.SetEndian( SvStreamEndian::BIG );
125 mnColors = mpAcc->GetPaletteEntryCount();
126 if ( ImplWriteHeader() )
128 ImplWritePalette();
129 ImplWriteBody();
130 m_rOStm.WriteCharPtr( "\x22XPMENDEXT\x22\x0a};" );
133 m_rOStm.SetEndian(nOStmOldModus);
135 Bitmap::ReleaseAccess( mpAcc );
137 else
138 mbStatus = false;
141 if ( xStatusIndicator.is() )
142 xStatusIndicator->end();
144 return mbStatus;
149 bool XPMWriter::ImplWriteHeader()
151 mnWidth = mpAcc->Width();
152 mnHeight = mpAcc->Height();
153 if ( mnWidth && mnHeight && mnColors )
155 m_rOStm.WriteCharPtr( "/* XPM */\x0astatic char * image[] = \x0a{\x0a\x22" );
156 ImplWriteNumber( mnWidth );
157 m_rOStm.WriteUChar( 32 );
158 ImplWriteNumber( mnHeight );
159 m_rOStm.WriteUChar( 32 );
160 ImplWriteNumber( mnColors );
161 m_rOStm.WriteUChar( 32 );
162 ImplWriteNumber( ( mnColors > 26 ) ? 2 : 1 );
163 m_rOStm.WriteCharPtr( "\x22,\x0a" );
165 else mbStatus = false;
166 return mbStatus;
171 void XPMWriter::ImplWritePalette()
173 sal_uInt16 nTransIndex = 0xffff;
175 if ( mbTrans )
176 nTransIndex = mpAcc->GetBestPaletteIndex( BMP_COL_TRANS );
177 for ( sal_uInt16 i = 0; i < mnColors; i++ )
179 m_rOStm.WriteCharPtr( "\x22" );
180 ImplWritePixel( i );
181 m_rOStm.WriteUChar( 32 );
182 if ( nTransIndex != i )
184 ImplWriteColor( i );
185 m_rOStm.WriteCharPtr( "\x22,\x0a" );
187 else
188 m_rOStm.WriteCharPtr( "c none\x22,\x0a" );
194 void XPMWriter::ImplWriteBody()
196 for ( sal_uLong y = 0; y < mnHeight; y++ )
198 ImplCallback( (sal_uInt16)( ( 100 * y ) / mnHeight ) ); // processing output in percent
199 m_rOStm.WriteUChar( 0x22 );
200 for ( sal_uLong x = 0; x < mnWidth; x++ )
202 ImplWritePixel( mpAcc->GetPixelIndex( y, x ) );
204 m_rOStm.WriteCharPtr( "\x22,\x0a" );
209 // write a decimal number in ascii format into the stream
211 void XPMWriter::ImplWriteNumber(sal_Int32 nNumber)
213 const OString aNum(OString::number(nNumber));
214 m_rOStm.WriteCharPtr( aNum.getStr() );
219 void XPMWriter::ImplWritePixel( sal_uLong nCol ) const
221 if ( mnColors > 26 )
223 sal_uInt8 nDiff = (sal_uInt8) ( nCol / 26 );
224 m_rOStm.WriteUChar( nDiff + 'A' );
225 m_rOStm.WriteUChar( nCol - ( nDiff*26 ) + 'A' );
227 else
228 m_rOStm.WriteUChar( nCol + 'A' );
232 // write a color value in hex format into the stream
233 void XPMWriter::ImplWriteColor( sal_uInt16 nNumber )
235 sal_uLong nTmp;
236 sal_uInt8 j;
238 m_rOStm.WriteCharPtr( "c #" ); // # indicates a following hex value
239 const BitmapColor& rColor = mpAcc->GetPaletteColor( nNumber );
240 nTmp = ( rColor.GetRed() << 16 ) | ( rColor.GetGreen() << 8 ) | rColor.GetBlue();
241 for ( signed char i = 20; i >= 0 ; i-=4 )
243 if ( ( j = (sal_uInt8)( nTmp >> i ) & 0xf ) > 9 )
244 j += 'A' - 10;
245 else
246 j += '0';
247 m_rOStm.WriteUChar( j );
253 // this needs to be kept in sync with
254 // ImpFilterLibCacheEntry::GetImportFunction() from
255 // vcl/source/filter/graphicfilter.cxx
256 #if defined(DISABLE_DYNLOADING)
257 #define GraphicExport expGraphicExport
258 #endif
260 extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
261 GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem )
263 XPMWriter aXPMWriter(rStream);
265 return aXPMWriter.WriteXPM( rGraphic, pFilterConfigItem );
269 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */