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 //============================ PGMWriter ==================================
36 
37 class PGMWriter {
38 
39 private:
40 
41 	SvStream*			mpOStm; 			// Die auszugebende PGM-Datei
42 	sal_uInt16				mpOStmOldModus;
43 
44 	sal_Bool				mbStatus;
45 	sal_uInt32				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 						PGMWriter();
57 						~PGMWriter();
58 
59 	sal_Bool				WritePGM( const Graphic& rGraphic, SvStream& rPGM, FilterConfigItem* pFilterConfigItem );
60 };
61 
62 //=================== Methoden von PGMWriter ==============================
63 
PGMWriter()64 PGMWriter::PGMWriter() :
65 	mbStatus	( sal_True ),
66 	mpAcc		( NULL )
67 {
68 }
69 
70 // ------------------------------------------------------------------------
71 
~PGMWriter()72 PGMWriter::~PGMWriter()
73 {
74 }
75 
76 // ------------------------------------------------------------------------
77 
WritePGM(const Graphic & rGraphic,SvStream & rPGM,FilterConfigItem * pFilterConfigItem)78 sal_Bool PGMWriter::WritePGM( const Graphic& rGraphic, SvStream& rPGM, FilterConfigItem* pFilterConfigItem )
79 {
80 
81 	mpOStm = &rPGM;
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_8BIT_GREYS );
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 PGMWriter::ImplWriteHeader()
125 {
126 	mnWidth = mpAcc->Width();
127 	mnHeight = mpAcc->Height();
128 	if ( mnWidth && mnHeight )
129 	{
130 		if ( mnMode == 0 )
131 			*mpOStm << "P5\x0a";
132 		else
133 			*mpOStm << "P2\x0a";
134 
135 		ImplWriteNumber( mnWidth );
136 		*mpOStm << (sal_uInt8)32;
137 		ImplWriteNumber( mnHeight );
138 		*mpOStm << (sal_uInt8)32;
139 		ImplWriteNumber( 255 ); 		// max. gray value
140 		*mpOStm << (sal_uInt8)10;
141 	}
142 	else
143 		mbStatus = sal_False;
144 
145 	return mbStatus;
146 }
147 
148 // ------------------------------------------------------------------------
149 
ImplWriteBody()150 void PGMWriter::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 				*mpOStm << mpAcc->GetPixelIndex( y, x );
159 			}
160 		}
161 	}
162 	else
163 	{
164 		for ( sal_uLong y = 0; y < mnHeight; y++ )
165 		{
166 			int nCount = 70;
167 			for ( sal_uLong x = 0; x < mnWidth; x++ )
168 			{
169 				sal_uInt8 nDat, nNumb;
170 				if ( nCount < 0 )
171 				{
172 					nCount = 69;
173 					*mpOStm << (sal_uInt8)10;
174 				}
175 				nDat = mpAcc->GetPixelIndex( y, x );
176                 nNumb = nDat / 100;
177 				if ( nNumb )
178 				{
179 					*mpOStm << (sal_uInt8)( nNumb + '0' );
180 					nDat -= ( nNumb * 100 );
181 					nNumb = nDat / 10;
182 					*mpOStm << (sal_uInt8)( nNumb + '0' );
183 					nDat -= ( nNumb * 10 );
184 					*mpOStm << (sal_uInt8)( nDat + '0' );
185 					nCount -= 4;
186 				}
187 				else
188                 {
189                     nNumb = nDat / 10;
190                     if ( nNumb )
191                     {
192                         *mpOStm << (sal_uInt8)( nNumb + '0' );
193                         nDat -= ( nNumb * 10 );
194                         *mpOStm << (sal_uInt8)( nDat + '0' );
195                         nCount -= 3;
196                     }
197                     else
198                     {
199                         *mpOStm << (sal_uInt8)( nDat + '0' );
200                         nCount -= 2;
201                     }
202                 }
203 				*mpOStm << (sal_uInt8)' ';
204 			}
205 			*mpOStm << (sal_uInt8)10;
206 		}
207 	}
208 }
209 
210 // ------------------------------------------------------------------------
211 // eine Dezimalzahl im ASCII format wird in den Stream geschrieben
212 
ImplWriteNumber(sal_Int32 nNumber)213 void PGMWriter::ImplWriteNumber( sal_Int32 nNumber )
214 {
215 	const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );
216 
217 	for( sal_Int16 n = 0UL, nLen = aNum.Len(); n < nLen; n++  )
218 		*mpOStm << aNum.GetChar( n );
219 
220 }
221 
222 // ------------------------------------------------------------------------
223 
224 // ---------------------
225 // - exported function -
226 // ---------------------
227 
GraphicExport(SvStream & rStream,Graphic & rGraphic,FilterConfigItem * pFilterConfigItem,sal_Bool)228 extern "C" sal_Bool __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool )
229 {
230 	PGMWriter aPGMWriter;
231 
232 	return aPGMWriter.WritePGM( rGraphic, rStream, pFilterConfigItem );
233 }
234 
235 // ------------------------------------------------------------------------
236