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