1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26
27 #include <vcl/svapp.hxx>
28 #include <vcl/graph.hxx>
29 #include <vcl/bmpacc.hxx>
30 #include <vcl/msgbox.hxx>
31 #include <svl/solar.hrc>
32 #include <svtools/fltcall.hxx>
33 #include <svtools/FilterConfigItem.hxx>
34
35 //============================ PBMWriter ==================================
36
37 class PBMWriter {
38
39 private:
40
41 SvStream* mpOStm; // Die auszugebende PBM-Datei
42 sal_uInt16 mpOStmOldModus;
43
44 sal_Bool mbStatus;
45 sal_Int32 mnMode; // 0 -> raw, 1-> ascii
46 BitmapReadAccess* mpAcc;
47 sal_uLong mnWidth, mnHeight; // Bildausmass in Pixeln
48
49 sal_Bool ImplWriteHeader();
50 void ImplWriteBody();
51 void ImplWriteNumber( sal_Int32 );
52
53 com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
54
55 public:
56 PBMWriter();
57 ~PBMWriter();
58
59 sal_Bool WritePBM( const Graphic& rGraphic, SvStream& rPBM, FilterConfigItem* pFilterConfigItem );
60 };
61
62 //=================== Methoden von PBMWriter ==============================
63
PBMWriter()64 PBMWriter::PBMWriter() :
65 mbStatus ( sal_True ),
66 mpAcc ( NULL )
67 {
68 }
69
70 // ------------------------------------------------------------------------
71
~PBMWriter()72 PBMWriter::~PBMWriter()
73 {
74 }
75
76 // ------------------------------------------------------------------------
77
WritePBM(const Graphic & rGraphic,SvStream & rPBM,FilterConfigItem * pFilterConfigItem)78 sal_Bool PBMWriter::WritePBM( const Graphic& rGraphic, SvStream& rPBM, FilterConfigItem* pFilterConfigItem )
79 {
80
81 mpOStm = &rPBM;
82
83 if ( pFilterConfigItem )
84 {
85 mnMode = pFilterConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "FileFormat" ) ), 0 );
86
87 xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
88 if ( xStatusIndicator.is() )
89 {
90 rtl::OUString aMsg;
91 xStatusIndicator->start( aMsg, 100 );
92 }
93 }
94
95 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
96 Bitmap aBmp = aBmpEx.GetBitmap();
97 aBmp.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
98
99 mpOStmOldModus = mpOStm->GetNumberFormatInt();
100 mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
101
102 mpAcc = aBmp.AcquireReadAccess();
103 if( mpAcc )
104 {
105 if ( ImplWriteHeader() )
106 ImplWriteBody();
107
108 aBmp.ReleaseAccess( mpAcc );
109 }
110 else
111 mbStatus = sal_False;
112
113 mpOStm->SetNumberFormatInt( mpOStmOldModus );
114
115 if ( xStatusIndicator.is() )
116 xStatusIndicator->end();
117
118 return mbStatus;
119 }
120
121 // ------------------------------------------------------------------------
122
ImplWriteHeader()123 sal_Bool PBMWriter::ImplWriteHeader()
124 {
125 mnWidth = mpAcc->Width();
126 mnHeight = mpAcc->Height();
127 if ( mnWidth && mnHeight )
128 {
129 if ( mnMode == 0 )
130 *mpOStm << "P4\x0a";
131 else
132 *mpOStm << "P1\x0a";
133
134 ImplWriteNumber( mnWidth );
135 *mpOStm << (sal_uInt8)32;
136 ImplWriteNumber( mnHeight );
137 *mpOStm << (sal_uInt8)10;
138 }
139 else mbStatus = sal_False;
140 return mbStatus;
141 }
142
143 // ------------------------------------------------------------------------
144
ImplWriteBody()145 void PBMWriter::ImplWriteBody()
146 {
147 if ( mnMode == 0 )
148 {
149 sal_uInt8 nBYTE = 0;
150 for ( sal_uLong y = 0; y < mnHeight; y++ )
151 {
152 sal_uLong x;
153 for ( x = 0; x < mnWidth; x++ )
154 {
155 nBYTE <<= 1;
156 if (!(mpAcc->GetPixelIndex( y, x ) & 1 ) )
157 nBYTE++;
158 if ( ( x & 7 ) == 7 )
159 *mpOStm << nBYTE;
160 }
161 if ( ( x & 7 ) != 0 )
162 *mpOStm << (sal_uInt8)( nBYTE << ( ( x ^ 7 ) + 1 ) );
163 }
164 }
165 else
166 {
167 int nxCount;
168 for ( sal_uLong y = 0; y < mnHeight; y++ )
169 {
170 nxCount = 70;
171 for ( sal_uLong x = 0; x < mnWidth; x++ )
172 {
173 if (!( --nxCount ) )
174 {
175 nxCount = 69;
176 *mpOStm << (sal_uInt8)10;
177 }
178 *mpOStm << (sal_uInt8)( ( mpAcc->GetPixelIndex( y, x ) ^ 1 ) + '0' ) ;
179 }
180 *mpOStm << (sal_uInt8)10;
181 }
182 }
183 }
184
185 // ------------------------------------------------------------------------
186 // eine Dezimalzahl im ASCII format wird in den Stream geschrieben
187
ImplWriteNumber(sal_Int32 nNumber)188 void PBMWriter::ImplWriteNumber( sal_Int32 nNumber )
189 {
190 const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );
191
192 for( sal_Int16 n = 0, nLen = aNum.Len(); n < nLen; n++ )
193 *mpOStm << aNum.GetChar( n );
194
195 }
196
197 // ------------------------------------------------------------------------
198
199 // ---------------------
200 // - exported function -
201 // ---------------------
202
GraphicExport(SvStream & rStream,Graphic & rGraphic,FilterConfigItem * pFilterConfigItem,sal_Bool)203 extern "C" sal_Bool __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool )
204 {
205 PBMWriter aPBMWriter;
206
207 return aPBMWriter.WritePBM( rGraphic, rStream, pFilterConfigItem );
208 }
209
210 // ------------------------------------------------------------------------
211