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