xref: /trunk/main/editeng/source/rtf/rtfgrf.cxx (revision 870262e3)
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_editeng.hxx"
26 
27 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
28 #include <osl/endian.h>
29 #include <tools/cachestr.hxx>
30 #include <vcl/graph.hxx>
31 #include <vcl/svapp.hxx>
32 #include <svtools/rtfkeywd.hxx>
33 #include <svtools/rtftoken.h>
34 #include <svtools/filter.hxx>
35 
36 #include <editeng/svxrtf.hxx>
37 
38 using namespace ::rtl;
39 
40 #ifndef DBG_UTIL
41 #undef DEBUG_JP
42 #endif
43 
44 #ifdef DEBUG_JP
45 
46 #include <tools/fsys.hxx>
47 
48 class GrfWindow : public WorkWindow
49 {
50 	Graphic aGrf;
51 public:
52 	GrfWindow( const Graphic& rGrf );
53 	virtual void    Paint( const Rectangle& rRect );
54 };
55 
GrfWindow(const Graphic & rGrf)56 GrfWindow::GrfWindow( const Graphic& rGrf )
57 	: WorkWindow( NULL ),
58 	aGrf( rGrf )
59 {
60 	SetPosSizePixel( Point( 100, 0 ), Size( 300, 300 ));
61 	Show();
62 	Invalidate();
63 	Update();
64 }
65 
Paint(const Rectangle &)66 void GrfWindow::Paint( const Rectangle& )
67 {
68 	aGrf.Draw( this, Point(0,0), GetSizePixel() );
69 }
70 #endif
71 
72 static sal_uInt8 __FAR_DATA aPal1[ 2 * 4 ] = {
73 		0x00, 0x00, 0x00, 0x00,				// Schwarz
74 		0xFF, 0xFF, 0xFF, 0x00				// Weiss
75 };
76 
77 static sal_uInt8 __FAR_DATA aPal4[ 16 * 4 ] = {
78 		0x00, 0x00, 0x00, 0x00,
79 		0x80, 0x00, 0x00, 0x00,
80 		0x00, 0x80, 0x00, 0x00,
81 		0x80, 0x80, 0x00, 0x00,
82 		0x00, 0x00, 0x80, 0x00,
83 		0x80, 0x00, 0x80, 0x00,
84 		0x00, 0x80, 0x80, 0x00,
85 		0x80, 0x80, 0x80, 0x00,
86 		0xC0, 0xC0, 0xC0, 0x00,
87 		0xFF, 0x00, 0x00, 0x00,
88 		0x00, 0xFF, 0x00, 0x00,
89 		0xFF, 0xFF, 0x00, 0x00,
90 		0x00, 0x00, 0xFF, 0x00,
91 		0xFF, 0x00, 0xFF, 0x00,
92 		0x00, 0xFF, 0xFF, 0x00,
93 		0xFF, 0xFF, 0xFF, 0x00
94 };
95 
96 static sal_uInt8 __FAR_DATA aPal8[ 256 * 4 ] =
97 {
98 0x00, 0x00, 0x00, 0x00,   0x80, 0x00, 0x00, 0x00,   0x00, 0x92, 0x00, 0x00,
99 0x80, 0x92, 0x00, 0x00,   0x00, 0x00, 0xAA, 0x00,   0x80, 0x00, 0xAA, 0x00,
100 0x00, 0x92, 0xAA, 0x00,   0xC1, 0xC1, 0xC1, 0x00,   0xC9, 0xC9, 0xC9, 0x00,
101 0xAA, 0xDB, 0xFF, 0x00,   0x00, 0x49, 0xAA, 0x00,   0x00, 0x49, 0xFF, 0x00,
102 0x00, 0x6D, 0x00, 0x00,   0x00, 0x6D, 0x55, 0x00,   0x00, 0x6D, 0xAA, 0x00,
103 0x00, 0x6D, 0xFF, 0x00,   0x00, 0x24, 0x00, 0x00,   0x00, 0x92, 0x55, 0x00,
104 0x00, 0x24, 0xAA, 0x00,   0x00, 0x92, 0xFF, 0x00,   0x00, 0xB6, 0x00, 0x00,
105 0x00, 0xB6, 0x55, 0x00,   0x00, 0xB6, 0xAA, 0x00,   0x00, 0xB6, 0xFF, 0x00,
106 0x00, 0xDB, 0x00, 0x00,   0x00, 0xDB, 0x55, 0x00,   0x00, 0xDB, 0xAA, 0x00,
107 0x00, 0xDB, 0xFF, 0x00,   0xFF, 0xDB, 0xAA, 0x00,   0x00, 0xFF, 0x55, 0x00,
108 0x00, 0xFF, 0xAA, 0x00,   0xFF, 0xFF, 0xAA, 0x00,   0x2B, 0x00, 0x00, 0x00,
109 0x2B, 0x00, 0x55, 0x00,   0x2B, 0x00, 0xAA, 0x00,   0x2B, 0x00, 0xFF, 0x00,
110 0x2B, 0x24, 0x00, 0x00,   0x2B, 0x24, 0x55, 0x00,   0x2B, 0x24, 0xAA, 0x00,
111 0x2B, 0x24, 0xFF, 0x00,   0x2B, 0x49, 0x00, 0x00,   0x2B, 0x49, 0x55, 0x00,
112 0x2B, 0x49, 0xAA, 0x00,   0x2B, 0x49, 0xFF, 0x00,   0x2B, 0x6D, 0x00, 0x00,
113 0x2B, 0x6D, 0x55, 0x00,   0x2B, 0x6D, 0xAA, 0x00,   0x2B, 0x6D, 0xFF, 0x00,
114 0x2B, 0x92, 0x00, 0x00,   0x2B, 0x92, 0x55, 0x00,   0x2B, 0x92, 0xAA, 0x00,
115 0x2B, 0x92, 0xFF, 0x00,   0x2B, 0xB6, 0x00, 0x00,   0x2B, 0xB6, 0x55, 0x00,
116 0x2B, 0xB6, 0xAA, 0x00,   0x2B, 0xB6, 0xFF, 0x00,   0x2B, 0xDB, 0x00, 0x00,
117 0x2B, 0xDB, 0x55, 0x00,   0x2B, 0xDB, 0xAA, 0x00,   0x2B, 0xDB, 0xFF, 0x00,
118 0x2B, 0xFF, 0x00, 0x00,   0x2B, 0xFF, 0x55, 0x00,   0x2B, 0xFF, 0xAA, 0x00,
119 0x2B, 0xFF, 0xFF, 0x00,   0x55, 0x00, 0x00, 0x00,   0x55, 0x00, 0x55, 0x00,
120 0x55, 0x00, 0xAA, 0x00,   0x55, 0x00, 0xFF, 0x00,   0x55, 0x24, 0x00, 0x00,
121 0x55, 0x24, 0x55, 0x00,   0x55, 0x24, 0xAA, 0x00,   0x55, 0x24, 0xFF, 0x00,
122 0x55, 0x49, 0x00, 0x00,   0x55, 0x49, 0x55, 0x00,   0x55, 0x49, 0xAA, 0x00,
123 0x55, 0x49, 0xFF, 0x00,   0x55, 0x6D, 0x00, 0x00,   0x55, 0x6D, 0x55, 0x00,
124 0x55, 0x6D, 0xAA, 0x00,   0x55, 0x6D, 0xFF, 0x00,   0x55, 0x92, 0x00, 0x00,
125 0x55, 0x92, 0x55, 0x00,   0x55, 0x92, 0xAA, 0x00,   0x55, 0x92, 0xFF, 0x00,
126 0x55, 0xB6, 0x00, 0x00,   0x55, 0xB6, 0x55, 0x00,   0x55, 0xB6, 0xAA, 0x00,
127 0x55, 0xB6, 0xFF, 0x00,   0x55, 0xDB, 0x00, 0x00,   0x55, 0xDB, 0x55, 0x00,
128 0x55, 0xDB, 0xAA, 0x00,   0x55, 0xDB, 0xFF, 0x00,   0x55, 0xFF, 0x00, 0x00,
129 0x55, 0xFF, 0x55, 0x00,   0x55, 0xFF, 0xAA, 0x00,   0x55, 0xFF, 0xFF, 0x00,
130 0x00, 0x00, 0x55, 0x00,   0x80, 0x00, 0x55, 0x00,   0x00, 0x24, 0x55, 0x00,
131 0x80, 0x00, 0xFF, 0x00,   0x80, 0x24, 0x00, 0x00,   0x80, 0x24, 0x55, 0x00,
132 0x80, 0x24, 0xAA, 0x00,   0x80, 0x24, 0xFF, 0x00,   0x80, 0x49, 0x00, 0x00,
133 0x80, 0x49, 0x55, 0x00,   0x80, 0x49, 0xAA, 0x00,   0x80, 0x49, 0xFF, 0x00,
134 0x80, 0x6D, 0x00, 0x00,   0x80, 0x6D, 0x55, 0x00,   0x80, 0x6D, 0xAA, 0x00,
135 0x80, 0x6D, 0xFF, 0x00,   0x08, 0x08, 0x08, 0x00,   0x0F, 0x0F, 0x0F, 0x00,
136 0x17, 0x17, 0x17, 0x00,   0x1F, 0x1F, 0x1F, 0x00,   0x27, 0x27, 0x27, 0x00,
137 0x2E, 0x2E, 0x2E, 0x00,   0x36, 0x36, 0x36, 0x00,   0x3E, 0x3E, 0x3E, 0x00,
138 0x46, 0x46, 0x46, 0x00,   0x4D, 0x4D, 0x4D, 0x00,   0x55, 0x55, 0x55, 0x00,
139 0x5D, 0x5D, 0x5D, 0x00,   0x64, 0x64, 0x64, 0x00,   0x6C, 0x6C, 0x6C, 0x00,
140 0x74, 0x74, 0x74, 0x00,   0x7C, 0x7C, 0x7C, 0x00,   0xFF, 0xDB, 0x00, 0x00,
141 0x8B, 0x8B, 0x8B, 0x00,   0x93, 0x93, 0x93, 0x00,   0x9B, 0x9B, 0x9B, 0x00,
142 0xFF, 0xB6, 0xFF, 0x00,   0xAA, 0xAA, 0xAA, 0x00,   0xB2, 0xB2, 0xB2, 0x00,
143 0xB9, 0xB9, 0xB9, 0x00,   0x00, 0x24, 0xFF, 0x00,   0x00, 0x49, 0x00, 0x00,
144 0xD1, 0xD1, 0xD1, 0x00,   0xD8, 0xD8, 0xD8, 0x00,   0xE0, 0xE0, 0xE0, 0x00,
145 0xE8, 0xE8, 0xE8, 0x00,   0xF0, 0xF0, 0xF0, 0x00,   0xFF, 0xB6, 0xAA, 0x00,
146 0xFF, 0xDB, 0xFF, 0x00,   0x80, 0x92, 0x55, 0x00,   0x80, 0x92, 0xAA, 0x00,
147 0x80, 0x92, 0xFF, 0x00,   0x80, 0xB6, 0x00, 0x00,   0x80, 0xB6, 0x55, 0x00,
148 0x80, 0xB6, 0xAA, 0x00,   0x80, 0xB6, 0xFF, 0x00,   0x80, 0xDB, 0x00, 0x00,
149 0x80, 0xDB, 0x55, 0x00,   0x80, 0xDB, 0xAA, 0x00,   0x80, 0xDB, 0xFF, 0x00,
150 0x80, 0xFF, 0x00, 0x00,   0x80, 0xFF, 0x55, 0x00,   0x80, 0xFF, 0xAA, 0x00,
151 0x80, 0xFF, 0xFF, 0x00,   0xAA, 0x00, 0x00, 0x00,   0xAA, 0x00, 0x55, 0x00,
152 0xAA, 0x00, 0xAA, 0x00,   0xAA, 0x00, 0xFF, 0x00,   0xAA, 0x24, 0x00, 0x00,
153 0xAA, 0x24, 0x55, 0x00,   0xAA, 0x24, 0xAA, 0x00,   0xAA, 0x24, 0xFF, 0x00,
154 0xAA, 0x49, 0x00, 0x00,   0xAA, 0x49, 0x55, 0x00,   0xAA, 0x49, 0xAA, 0x00,
155 0xAA, 0x49, 0xFF, 0x00,   0xAA, 0x6D, 0x00, 0x00,   0xAA, 0x6D, 0x55, 0x00,
156 0xAA, 0x6D, 0xAA, 0x00,   0xAA, 0x6D, 0xFF, 0x00,   0xAA, 0x92, 0x00, 0x00,
157 0xAA, 0x92, 0x55, 0x00,   0xAA, 0x92, 0xAA, 0x00,   0xAA, 0x92, 0xFF, 0x00,
158 0xAA, 0xB6, 0x00, 0x00,   0xAA, 0xB6, 0x55, 0x00,   0xAA, 0xB6, 0xAA, 0x00,
159 0xAA, 0xB6, 0xFF, 0x00,   0xAA, 0xDB, 0x00, 0x00,   0xAA, 0xDB, 0x55, 0x00,
160 0xAA, 0xDB, 0xAA, 0x00,   0x00, 0x49, 0x55, 0x00,   0xAA, 0xFF, 0x00, 0x00,
161 0xAA, 0xFF, 0x55, 0x00,   0xAA, 0xFF, 0xAA, 0x00,   0xAA, 0xFF, 0xFF, 0x00,
162 0xD5, 0x00, 0x00, 0x00,   0xD5, 0x00, 0x55, 0x00,   0xD5, 0x00, 0xAA, 0x00,
163 0xD5, 0x00, 0xFF, 0x00,   0xD5, 0x24, 0x00, 0x00,   0xD5, 0x24, 0x55, 0x00,
164 0xD5, 0x24, 0xAA, 0x00,   0xD5, 0x24, 0xFF, 0x00,   0xD5, 0x49, 0x00, 0x00,
165 0xD5, 0x49, 0x55, 0x00,   0xD5, 0x49, 0xAA, 0x00,   0xD5, 0x49, 0xFF, 0x00,
166 0xD5, 0x6D, 0x00, 0x00,   0xD5, 0x6D, 0x55, 0x00,   0xD5, 0x6D, 0xAA, 0x00,
167 0xD5, 0x6D, 0xFF, 0x00,   0xD5, 0x92, 0x00, 0x00,   0xD5, 0x92, 0x55, 0x00,
168 0xD5, 0x92, 0xAA, 0x00,   0xD5, 0x92, 0xFF, 0x00,   0xD5, 0xB6, 0x00, 0x00,
169 0xD5, 0xB6, 0x55, 0x00,   0xD5, 0xB6, 0xAA, 0x00,   0xD5, 0xB6, 0xFF, 0x00,
170 0xD5, 0xDB, 0x00, 0x00,   0xD5, 0xDB, 0x55, 0x00,   0xD5, 0xDB, 0xAA, 0x00,
171 0xD5, 0xDB, 0xFF, 0x00,   0xD5, 0xFF, 0x00, 0x00,   0xD5, 0xFF, 0x55, 0x00,
172 0xD5, 0xFF, 0xAA, 0x00,   0xD5, 0xFF, 0xFF, 0x00,   0xFF, 0xDB, 0x55, 0x00,
173 0xFF, 0x00, 0x55, 0x00,   0xFF, 0x00, 0xAA, 0x00,   0xFF, 0xFF, 0x55, 0x00,
174 0xFF, 0x24, 0x00, 0x00,   0xFF, 0x24, 0x55, 0x00,   0xFF, 0x24, 0xAA, 0x00,
175 0xFF, 0x24, 0xFF, 0x00,   0xFF, 0x49, 0x00, 0x00,   0xFF, 0x49, 0x55, 0x00,
176 0xFF, 0x49, 0xAA, 0x00,   0xFF, 0x49, 0xFF, 0x00,   0xFF, 0x6D, 0x00, 0x00,
177 0xFF, 0x6D, 0x55, 0x00,   0xFF, 0x6D, 0xAA, 0x00,   0xFF, 0x6D, 0xFF, 0x00,
178 0xFF, 0x92, 0x00, 0x00,   0xFF, 0x92, 0x55, 0x00,   0xFF, 0x92, 0xAA, 0x00,
179 0xFF, 0x92, 0xFF, 0x00,   0xFF, 0xB6, 0x00, 0x00,   0xFF, 0xB6, 0x55, 0x00,
180 0xF7, 0xF7, 0xF7, 0x00,   0xA2, 0xA2, 0xA2, 0x00,   0x83, 0x83, 0x83, 0x00,
181 0xFF, 0x00, 0x00, 0x00,   0x00, 0xFF, 0x00, 0x00,   0xFF, 0xFF, 0x00, 0x00,
182 0x00, 0x00, 0xFF, 0x00,   0xFF, 0x00, 0xFF, 0x00,   0x00, 0xFF, 0xFF, 0x00,
183 0xFF, 0xFF, 0xFF, 0x00
184 };
185 
186 
187 /*  */
188 
189 
SwapLong(long n)190 inline long SwapLong( long n )
191 {
192 #ifndef OSL_LITENDIAN
193 	return SWAPLONG( n );
194 #else
195 	return n;
196 #endif
197 }
198 
SwapShort(short n)199 inline short SwapShort( short n )
200 {
201 #ifndef OSL_LITENDIAN
202 	return SWAPSHORT( n );
203 #else
204 	return n;
205 #endif
206 }
207 
208 
WriteBMPHeader(SvStream & rStream,const SvxRTFPictureType & rPicType)209 static void WriteBMPHeader( SvStream& rStream,
210 							const SvxRTFPictureType& rPicType )
211 {
212 	sal_uInt32 n4Width = rPicType.nWidth;
213 	sal_uInt32 n4Height = rPicType.nHeight;
214 	sal_uInt16 n4ColBits = rPicType.nBitsPerPixel;
215 
216 	sal_uInt16 nColors = (1 << n4ColBits);	// Anzahl der Farben ( 1, 16, 256 )
217 	sal_uInt16 nWdtOut = rPicType.nWidthBytes;
218 	if( !nWdtOut )
219 		nWdtOut = (sal_uInt16)((( n4Width * n4ColBits + 31 ) / 32 ) * 4 );
220 
221 	long nOffset = 14 + 40; 	// BMP_FILE_HD_SIZ + sizeof(*pBmpInfo);
222 	if( 256 >= nColors )
223 		nOffset += nColors * 4;
224 	long nSize = nOffset + nWdtOut * n4Height;
225 	rStream << "BM"						// = "BM"
226 			<< SwapLong(nSize)          // Filesize in Bytes
227 			<< SwapShort(0)             // Reserviert
228 			<< SwapShort(0)             // Reserviert
229 			<< SwapLong(nOffset);       // Offset?
230 
231 	rStream	<< SwapLong(40)				// sizeof( BmpInfo )
232 			<< SwapLong(n4Width)
233 			<< SwapLong(n4Height)
234 			<< (sal_uInt16)1
235 			<< n4ColBits
236 			<< SwapLong(0)
237 			<< SwapLong(0)
238 			<< SwapLong( rPicType.nGoalWidth
239 						? rPicType.nGoalWidth * 1000L / 254L
240 						: 0 )	      // DPI in Pixel per Meter
241 			<< SwapLong( rPicType.nGoalHeight
242 						? rPicType.nGoalHeight * 1000L / 254L      // dito
243 						: 0 )
244 			<< SwapLong(0)
245 			<< SwapLong(0);
246 
247 
248 	switch( rPicType.nBitsPerPixel )
249 	{
250 	case 1:		rStream.Write( aPal1, sizeof( aPal1 ));	break;
251 	case 4:		rStream.Write( aPal4, sizeof( aPal4 ));	break;
252 	case 8:		rStream.Write( aPal8, sizeof( aPal8 ));	break;
253 	}
254 }
255 
256 /*  */
257 
258 		// wandel die ASCII-HexCodes in binaere Zeichen um. Werden
259 		// ungueltige Daten gefunden (Zeichen ausser 0-9|a-f|A-F, so
260 		// wird USHRT_MAX returnt, ansonsten die Anzahl der umgewandelten Ze.
HexToBin(String & rToken)261 xub_StrLen SvxRTFParser::HexToBin( String& rToken )
262 {
263 	// dann mache aus den Hex-Werten mal "Binare Daten"
264 	// (missbrauche den String als temp Buffer)
265 	if( rToken.Len() & 1 )		// ungerade Anzahl, mit 0 auffuellen
266 		rToken += '0';
267 
268 	xub_StrLen n, nLen;
269 	sal_Unicode nVal;
270 	sal_Bool bValidData = sal_True;
271 	const sal_Unicode* pStr = rToken.GetBufferAccess();
272 	sal_Char* pData = (sal_Char*)pStr;
273 	for( n = 0, nLen = rToken.Len(); n < nLen; ++n, ++pStr )
274 	{
275 		if( ((nVal = *pStr) >= '0') && ( nVal <= '9') )
276 			nVal -= '0';
277 		else if( (nVal >= 'A') && (nVal <= 'F') )
278 			nVal -= 'A' - 10;
279 		else if( (nVal >= 'a') && (nVal <= 'f') )
280 			nVal -= 'a' - 10;
281 		else
282 		{
283 			DBG_ASSERT( sal_False, "invalid hex value" );
284 			bValidData = sal_False;
285 			break;
286 		}
287 
288 		if( n & 1 )
289 			*(pData++) |= nVal & 0x0f;
290 		else
291 			*(pData) = sal::static_int_cast< char >( ( nVal << 4 ) & 0xf0 );
292 	}
293 	// the len div 2, because 2 character are one byte
294 	return bValidData ? nLen / 2  : STRING_NOTFOUND;
295 }
296 
ReadBmpData(Graphic & rGrf,SvxRTFPictureType & rPicType)297 sal_Bool SvxRTFParser::ReadBmpData( Graphic& rGrf, SvxRTFPictureType& rPicType )
298 {
299 	// die alten Daten loeschen
300 	rGrf.Clear();
301 //	sal_uInt32 nBmpSize = 0;
302 
303 	rtl_TextEncoding eOldEnc = GetSrcEncoding();
304 	SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
305 
306 	const sal_Char* pFilterNm = 0;
307 	SvCacheStream* pTmpFile = 0;
308 
309 	int nToken = 0;
310     bool bValidBmp = true, bFirstTextToken = true;
311 	int _nOpenBrakets = 1,		// die erste wurde schon vorher erkannt !!
312 		nValidDataBraket = 1;
313 
314 	if( RTF_SHPPICT == GetStackPtr(0)->nTokenId )
315 		++nValidDataBraket;
316     OUString sShapePropertyName, sShapePropertyValue;
317     int nShapePropertyBracket = -1;
318 	while( _nOpenBrakets && IsParserWorking() && bValidBmp )
319 	{
320 		nToken = GetNextToken();
321 		sal_uInt16 nVal = sal_uInt16( nTokenValue );
322 		switch( nToken )
323 		{
324         case '}':
325             --_nOpenBrakets;
326             if( nShapePropertyBracket > 0 && nShapePropertyBracket > _nOpenBrakets )
327             {
328                 nShapePropertyBracket = -1;
329                 if( sShapePropertyName.getLength() )
330                 {
331                     rPicType.aPropertyPairs.push_back( ::std::pair< OUString, OUString >( sShapePropertyName, sShapePropertyValue ) );
332                     sShapePropertyName = sShapePropertyValue = ::rtl::OUString();
333                 }
334             }
335         break;
336 		case '{':
337 			{
338 				if( RTF_IGNOREFLAG != GetNextToken() )
339 					nToken = SkipToken( -1 );
340 				else if( RTF_UNKNOWNCONTROL != GetNextToken() )
341 					nToken = SkipToken( -2 );
342 				else
343 				{
344 					// gleich herausfiltern
345 					ReadUnknownData();
346 					nToken = GetNextToken();
347 					if( '}' != nToken )
348 						eState = SVPAR_ERROR;
349 					break;
350 				}
351 				++_nOpenBrakets;
352 			}
353 			break;
354 
355 		case RTF_MACPICT:
356 			{
357 				rPicType.eStyle = SvxRTFPictureType::MAC_QUICKDRAW;
358 				// Mac-Pict bekommt einen leeren Header voran
359 				pTmpFile = new SvCacheStream;
360 				ByteString aStr;
361 				aStr.Fill( 512, '\0' );
362 				pTmpFile->Write( aStr.GetBuffer(), aStr.Len() );
363 				pFilterNm = "PCT";
364 			}
365 			break;
366 
367 		case RTF_EMFBLIP:
368 		case RTF_WMETAFILE:
369 		case RTF_PNGBLIP:
370 		case RTF_JPEGBLIP:
371 		case RTF_WBITMAP:
372 		case RTF_OSMETAFILE:
373 		case RTF_DIBITMAP:
374 			{
375 				switch( nToken )
376 				{
377 				case RTF_EMFBLIP:
378 					rPicType.eStyle = SvxRTFPictureType::ENHANCED_MF;
379 					pFilterNm = "EMF";
380 					break;
381 				case RTF_WMETAFILE:
382 					rPicType.eStyle = SvxRTFPictureType::WIN_METAFILE;
383 					pFilterNm = "WMF";
384 					break;
385 				case RTF_PNGBLIP:
386 					rPicType.eStyle = SvxRTFPictureType::RTF_PNG;
387 					pFilterNm = "PNG";
388 					break;
389 				case RTF_JPEGBLIP:
390 					rPicType.eStyle = SvxRTFPictureType::RTF_JPG;
391 					pFilterNm = "JPG";
392 					break;
393 
394 				case RTF_WBITMAP:
395 					rPicType.eStyle = SvxRTFPictureType::RTF_BITMAP;
396 					break;
397 				case RTF_OSMETAFILE:
398 					rPicType.eStyle = SvxRTFPictureType::OS2_METAFILE;
399 					break;
400 				case RTF_DIBITMAP:
401 					rPicType.eStyle = SvxRTFPictureType::RTF_DI_BMP;
402 					break;
403 				}
404 
405 				rPicType.nType = nVal;
406 				pTmpFile = new SvCacheStream;
407 			}
408 			break;
409 
410 		case RTF_PICW:				rPicType.nWidth = nVal; break;
411 		case RTF_PICH:				rPicType.nHeight = nVal; break;
412 		case RTF_WBMBITSPIXEL:		rPicType.nBitsPerPixel = nVal; break;
413 		case RTF_WBMPLANES: 		rPicType.nPlanes = nVal; break;
414 		case RTF_WBMWIDTHBYTES:		rPicType.nWidthBytes = nVal; break;
415 		case RTF_PICWGOAL:			rPicType.nGoalWidth = nVal; break;
416 		case RTF_PICHGOAL:			rPicType.nGoalHeight = nVal; break;
417 		case RTF_BIN:
418             rPicType.nMode = SvxRTFPictureType::BINARY_MODE;
419 			rPicType.uPicLen = nTokenValue;
420             if (rPicType.uPicLen)
421             {
422                 sal_uInt32 nPos = rStrm.Tell();
423                 nPos = nPos;
424                 rStrm.SeekRel(-1);
425                 sal_uInt8 aData[4096];
426                 sal_uInt32 nSize = sizeof(aData);
427 
428                 while (rPicType.uPicLen > 0)
429                 {
430                     if (rPicType.uPicLen < nSize)
431                         nSize = rPicType.uPicLen;
432 
433                     rStrm.Read(aData, nSize);
434                     pTmpFile->Write(aData, nSize);
435                     rPicType.uPicLen -= nSize;
436                 }
437                 nNextCh = GetNextChar();
438                 bValidBmp = !pTmpFile->GetError();
439                 nPos = rStrm.Tell();
440                 nPos = nPos;
441             }
442             break;
443 		case RTF_PICSCALEX:			rPicType.nScalX = nVal; break;
444 		case RTF_PICSCALEY:			rPicType.nScalY = nVal; break;
445 		case RTF_PICSCALED: 		break;
446 
447 		case RTF_PICCROPT:			rPicType.nCropT = (short)nTokenValue; break;
448 		case RTF_PICCROPB:			rPicType.nCropB = (short)nTokenValue; break;
449 		case RTF_PICCROPL:			rPicType.nCropL = (short)nTokenValue; break;
450 		case RTF_PICCROPR:			rPicType.nCropR = (short)nTokenValue; break;
451         case RTF_SP:
452             //read pairs of {\sn Name}{\sv Value}
453             nShapePropertyBracket = _nOpenBrakets;
454         break;
455         case RTF_SN:
456             nToken = GetNextToken();
457             if( nToken != '}' )
458                 sShapePropertyName = aToken;
459             else
460                 nToken = SkipToken( -1 );
461         break;
462         case RTF_SV:
463             nToken = GetNextToken();
464             if( nToken != '}' )
465                 sShapePropertyValue = aToken;
466             else
467                 nToken = SkipToken( -1 );
468         break;
469 		case RTF_TEXTTOKEN:
470 			// JP 26.06.98: Bug #51719# - nur TextToken auf 1. Ebene
471 			//				auswerten. Alle anderen sind irgendwelche
472 			//				nicht auszuwertende Daten
473 			if( nValidDataBraket != _nOpenBrakets )
474 				break;
475 
476 			if( bFirstTextToken )
477 			{
478 				switch( rPicType.eStyle )
479 				{
480 				case SvxRTFPictureType::RTF_BITMAP:
481 					// erstmal die Header und Info-Struktur schreiben
482 					if( pTmpFile )
483 						::WriteBMPHeader( *pTmpFile, rPicType );
484 					break;
485 				default:
486 					break;
487 				}
488 				bFirstTextToken = sal_False;
489 			}
490 
491 			if( pTmpFile && SvxRTFPictureType::HEX_MODE == rPicType.nMode )
492 			{
493 				xub_StrLen nTokenLen = HexToBin( aToken );
494 				if( STRING_NOTFOUND == nTokenLen )
495 					bValidBmp = sal_False;
496 				else
497 				{
498 					pTmpFile->Write( (sal_Char*)aToken.GetBuffer(),
499 										nTokenLen );
500 					bValidBmp = 0 == pTmpFile->GetError();
501 				}
502 			}
503 			break;
504 		}
505 	}
506 
507 	if (pTmpFile)
508 	{
509         //#i20775#
510         if (pTmpFile->Tell() == 0)
511             bValidBmp = false;
512 
513 		if( bValidBmp )
514 		{
515 			GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
516 			sal_uInt16 nImportFilter = GRFILTER_FORMAT_DONTKNOW;
517 
518 			if( pFilterNm )
519 			{
520 				String sTmp;
521 				for( sal_uInt16 n = pGF->GetImportFormatCount(); n; )
522 				{
523 					sTmp = pGF->GetImportFormatShortName( --n );
524 					if( sTmp.EqualsAscii( pFilterNm ))
525 					{
526 						nImportFilter = n;
527 						break;
528 					}
529 				}
530 			}
531 
532 			String sTmpStr;
533 			pTmpFile->Seek( STREAM_SEEK_TO_BEGIN );
534 			bValidBmp = 0 == pGF->ImportGraphic( rGrf, sTmpStr, *pTmpFile,
535 												nImportFilter );
536 		}
537 		delete pTmpFile;
538 	}
539 
540 	if( !bValidBmp )
541 	{
542 		rGrf.Clear();
543         //TODO  If nToken were not initialized to 0 above, it would potentially
544         // be used uninitialized here (if IsParserWorking() is false at the
545         // start of the while loop above):
546 		if( '}' != nToken )
547 			SkipGroup();
548 	}
549 	else
550 	{
551 		switch( rPicType.eStyle )
552 		{
553 //??		ENHANCED_MF,		// in den Pict.Daten steht ein Enhanced-Metafile
554 		case SvxRTFPictureType::RTF_PNG:
555 		case SvxRTFPictureType::RTF_JPG:
556 			{
557 				const MapMode aMap( MAP_100TH_MM );
558 			 	Size aSize( rGrf.GetPrefSize() );
559 				if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
560 					aSize = Application::GetDefaultDevice()->PixelToLogic(
561 										aSize, aMap );
562 				else
563 					aSize = OutputDevice::LogicToLogic( aSize,
564 										rGrf.GetPrefMapMode(), aMap );
565 				rPicType.nWidth = sal::static_int_cast< sal_uInt16 >(aSize.Width());
566 				rPicType.nHeight = sal::static_int_cast< sal_uInt16 >(
567                     aSize.Height());
568 			}
569 			break;
570 		default:
571 			break;
572 		}
573 
574 #ifdef DEBUG_JP
575 		new GrfWindow( rGrf );
576 #endif
577 	}
578 	SetSrcEncoding( eOldEnc );
579 
580 	SkipToken( -1 );		// die schliesende Klammer wird "oben" ausgewertet
581 	return bValidBmp;
582 }
583 
584 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
585