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 //============================ PPMWriter ==================================
36
37 class PPMWriter {
38
39 private:
40
41 SvStream* mpOStm; // Die auszugebende PPM-Datei
42 sal_uInt16 mpOStmOldModus;
43
44 sal_Bool mbStatus;
45 sal_Int32 mnMode;
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 PPMWriter();
57 ~PPMWriter();
58
59 sal_Bool WritePPM( const Graphic& rGraphic, SvStream& rPPM, FilterConfigItem* pFilterConfigItem );
60 };
61
62 //=================== Methoden von PPMWriter ==============================
63
PPMWriter()64 PPMWriter::PPMWriter() :
65 mbStatus ( sal_True ),
66 mpAcc ( NULL )
67 {
68 }
69
70 // ------------------------------------------------------------------------
71
~PPMWriter()72 PPMWriter::~PPMWriter()
73 {
74 }
75
76 // ------------------------------------------------------------------------
77
WritePPM(const Graphic & rGraphic,SvStream & rPPM,FilterConfigItem * pFilterConfigItem)78 sal_Bool PPMWriter::WritePPM( const Graphic& rGraphic, SvStream& rPPM, FilterConfigItem* pFilterConfigItem )
79 {
80
81 mpOStm = &rPPM;
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_24BIT );
98
99 mpOStmOldModus = mpOStm->GetNumberFormatInt();
100 mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
101
102 mpAcc = aBmp.AcquireReadAccess();
103 if( mpAcc )
104 {
105 if ( ImplWriteHeader() )
106 {
107 ImplWriteBody();
108 }
109 aBmp.ReleaseAccess( mpAcc );
110 }
111 else
112 mbStatus = sal_False;
113
114 mpOStm->SetNumberFormatInt( mpOStmOldModus );
115
116 if ( xStatusIndicator.is() )
117 xStatusIndicator->end();
118
119 return mbStatus;
120 }
121
122 // ------------------------------------------------------------------------
123
ImplWriteHeader()124 sal_Bool PPMWriter::ImplWriteHeader()
125 {
126 mnWidth = mpAcc->Width();
127 mnHeight = mpAcc->Height();
128 if ( mnWidth && mnHeight )
129 {
130 if ( mnMode == 0 )
131 *mpOStm << "P6\x0a";
132 else
133 *mpOStm << "P3\x0a";
134
135 ImplWriteNumber( mnWidth );
136 *mpOStm << (sal_uInt8)32;
137 ImplWriteNumber( mnHeight );
138 *mpOStm << (sal_uInt8)32;
139 ImplWriteNumber( 255 ); // max. col.
140 *mpOStm << (sal_uInt8)10;
141 }
142 else
143 mbStatus = sal_False;
144
145 return mbStatus;
146 }
147
148 // ------------------------------------------------------------------------
149
ImplWriteBody()150 void PPMWriter::ImplWriteBody()
151 {
152 if ( mnMode == 0 )
153 {
154 for ( sal_uLong y = 0; y < mnHeight; y++ )
155 {
156 for ( sal_uLong x = 0; x < mnWidth; x++ )
157 {
158 const BitmapColor& rColor = mpAcc->GetPixel( y, x );
159 *mpOStm << rColor.GetRed();
160 *mpOStm << rColor.GetGreen();
161 *mpOStm << rColor.GetBlue();
162 }
163 }
164 }
165 else
166 {
167 for ( sal_uLong y = 0; y < mnHeight; y++ )
168 {
169 int nCount = 70;
170 for ( sal_uLong x = 0; x < mnWidth; x++ )
171 {
172 sal_uInt8 i, nDat[3], nNumb;
173 if ( nCount < 0 )
174 {
175 nCount = 69;
176 *mpOStm << (sal_uInt8)10;
177 }
178 nDat[0] = mpAcc->GetPixel( y, x ).GetRed();
179 nDat[1] = mpAcc->GetPixel( y, x ).GetGreen();
180 nDat[2] = mpAcc->GetPixel( y, x ).GetBlue();
181 for ( i = 0; i < 3; i++ )
182 {
183 nNumb = nDat[ i ] / 100;
184 if ( nNumb )
185 {
186 *mpOStm << (sal_uInt8)( nNumb + '0' );
187 nDat[ i ] -= ( nNumb * 100 );
188 nNumb = nDat[ i ] / 10;
189 *mpOStm << (sal_uInt8)( nNumb + '0' );
190 nDat[ i ] -= ( nNumb * 10 );
191 *mpOStm << (sal_uInt8)( nDat[ i ] + '0' );
192 nCount -= 4;
193 }
194 else
195 {
196 nNumb = nDat[ i ] / 10;
197 if ( nNumb )
198 {
199 *mpOStm << (sal_uInt8)( nNumb + '0' );
200 nDat[ i ] -= ( nNumb * 10 );
201 *mpOStm << (sal_uInt8)( nDat[ i ] + '0' );
202 nCount -= 3;
203 }
204 else
205 {
206 *mpOStm << (sal_uInt8)( nDat[ i ] + '0' );
207 nCount -= 2;
208 }
209 }
210 *mpOStm << (sal_uInt8)' ';
211 }
212 }
213 *mpOStm << (sal_uInt8)10;
214 }
215 }
216 }
217
218 // ------------------------------------------------------------------------
219 // eine Dezimalzahl im ASCII format wird in den Stream geschrieben
220
ImplWriteNumber(sal_Int32 nNumber)221 void PPMWriter::ImplWriteNumber( sal_Int32 nNumber )
222 {
223 const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );
224
225 for( sal_Int16 n = 0, nLen = aNum.Len(); n < nLen; n++ )
226 *mpOStm << aNum.GetChar( n );
227
228 }
229
230 // ------------------------------------------------------------------------
231
232 // ---------------------
233 // - exported function -
234 // ---------------------
235
GraphicExport(SvStream & rStream,Graphic & rGraphic,FilterConfigItem * pFilterConfigItem,sal_Bool)236 extern "C" sal_Bool __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool )
237 {
238 PPMWriter aPPMWriter;
239 return aPPMWriter.WritePPM( rGraphic, rStream, pFilterConfigItem );
240 }
241
242 // ------------------------------------------------------------------------
243
244