Bump for 3.6-28
[LibreOffice.git] / editeng / source / rtf / rtfgrf.cxx
bloba0bd5cd1c046e026628285392e2cc709aff0260c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <boost/scoped_ptr.hpp>
32 #include <osl/endian.h>
33 #include <tools/cachestr.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/svapp.hxx>
36 #include <svtools/rtfkeywd.hxx>
37 #include <svtools/rtftoken.h>
38 #include <vcl/graphicfilter.hxx>
39 #include <vcl/wmf.hxx>
41 #include <editeng/svxrtf.hxx>
43 #include <vector>
45 using namespace ::rtl;
47 static sal_uInt8 aPal1[ 2 * 4 ] = {
48 0x00, 0x00, 0x00, 0x00, // Black
49 0xFF, 0xFF, 0xFF, 0x00 // White
52 static sal_uInt8 aPal4[ 16 * 4 ] = {
53 0x00, 0x00, 0x00, 0x00,
54 0x80, 0x00, 0x00, 0x00,
55 0x00, 0x80, 0x00, 0x00,
56 0x80, 0x80, 0x00, 0x00,
57 0x00, 0x00, 0x80, 0x00,
58 0x80, 0x00, 0x80, 0x00,
59 0x00, 0x80, 0x80, 0x00,
60 0x80, 0x80, 0x80, 0x00,
61 0xC0, 0xC0, 0xC0, 0x00,
62 0xFF, 0x00, 0x00, 0x00,
63 0x00, 0xFF, 0x00, 0x00,
64 0xFF, 0xFF, 0x00, 0x00,
65 0x00, 0x00, 0xFF, 0x00,
66 0xFF, 0x00, 0xFF, 0x00,
67 0x00, 0xFF, 0xFF, 0x00,
68 0xFF, 0xFF, 0xFF, 0x00
71 static sal_uInt8 aPal8[ 256 * 4 ] =
73 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00,
74 0x80, 0x92, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x80, 0x00, 0xAA, 0x00,
75 0x00, 0x92, 0xAA, 0x00, 0xC1, 0xC1, 0xC1, 0x00, 0xC9, 0xC9, 0xC9, 0x00,
76 0xAA, 0xDB, 0xFF, 0x00, 0x00, 0x49, 0xAA, 0x00, 0x00, 0x49, 0xFF, 0x00,
77 0x00, 0x6D, 0x00, 0x00, 0x00, 0x6D, 0x55, 0x00, 0x00, 0x6D, 0xAA, 0x00,
78 0x00, 0x6D, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x92, 0x55, 0x00,
79 0x00, 0x24, 0xAA, 0x00, 0x00, 0x92, 0xFF, 0x00, 0x00, 0xB6, 0x00, 0x00,
80 0x00, 0xB6, 0x55, 0x00, 0x00, 0xB6, 0xAA, 0x00, 0x00, 0xB6, 0xFF, 0x00,
81 0x00, 0xDB, 0x00, 0x00, 0x00, 0xDB, 0x55, 0x00, 0x00, 0xDB, 0xAA, 0x00,
82 0x00, 0xDB, 0xFF, 0x00, 0xFF, 0xDB, 0xAA, 0x00, 0x00, 0xFF, 0x55, 0x00,
83 0x00, 0xFF, 0xAA, 0x00, 0xFF, 0xFF, 0xAA, 0x00, 0x2B, 0x00, 0x00, 0x00,
84 0x2B, 0x00, 0x55, 0x00, 0x2B, 0x00, 0xAA, 0x00, 0x2B, 0x00, 0xFF, 0x00,
85 0x2B, 0x24, 0x00, 0x00, 0x2B, 0x24, 0x55, 0x00, 0x2B, 0x24, 0xAA, 0x00,
86 0x2B, 0x24, 0xFF, 0x00, 0x2B, 0x49, 0x00, 0x00, 0x2B, 0x49, 0x55, 0x00,
87 0x2B, 0x49, 0xAA, 0x00, 0x2B, 0x49, 0xFF, 0x00, 0x2B, 0x6D, 0x00, 0x00,
88 0x2B, 0x6D, 0x55, 0x00, 0x2B, 0x6D, 0xAA, 0x00, 0x2B, 0x6D, 0xFF, 0x00,
89 0x2B, 0x92, 0x00, 0x00, 0x2B, 0x92, 0x55, 0x00, 0x2B, 0x92, 0xAA, 0x00,
90 0x2B, 0x92, 0xFF, 0x00, 0x2B, 0xB6, 0x00, 0x00, 0x2B, 0xB6, 0x55, 0x00,
91 0x2B, 0xB6, 0xAA, 0x00, 0x2B, 0xB6, 0xFF, 0x00, 0x2B, 0xDB, 0x00, 0x00,
92 0x2B, 0xDB, 0x55, 0x00, 0x2B, 0xDB, 0xAA, 0x00, 0x2B, 0xDB, 0xFF, 0x00,
93 0x2B, 0xFF, 0x00, 0x00, 0x2B, 0xFF, 0x55, 0x00, 0x2B, 0xFF, 0xAA, 0x00,
94 0x2B, 0xFF, 0xFF, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x55, 0x00,
95 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xFF, 0x00, 0x55, 0x24, 0x00, 0x00,
96 0x55, 0x24, 0x55, 0x00, 0x55, 0x24, 0xAA, 0x00, 0x55, 0x24, 0xFF, 0x00,
97 0x55, 0x49, 0x00, 0x00, 0x55, 0x49, 0x55, 0x00, 0x55, 0x49, 0xAA, 0x00,
98 0x55, 0x49, 0xFF, 0x00, 0x55, 0x6D, 0x00, 0x00, 0x55, 0x6D, 0x55, 0x00,
99 0x55, 0x6D, 0xAA, 0x00, 0x55, 0x6D, 0xFF, 0x00, 0x55, 0x92, 0x00, 0x00,
100 0x55, 0x92, 0x55, 0x00, 0x55, 0x92, 0xAA, 0x00, 0x55, 0x92, 0xFF, 0x00,
101 0x55, 0xB6, 0x00, 0x00, 0x55, 0xB6, 0x55, 0x00, 0x55, 0xB6, 0xAA, 0x00,
102 0x55, 0xB6, 0xFF, 0x00, 0x55, 0xDB, 0x00, 0x00, 0x55, 0xDB, 0x55, 0x00,
103 0x55, 0xDB, 0xAA, 0x00, 0x55, 0xDB, 0xFF, 0x00, 0x55, 0xFF, 0x00, 0x00,
104 0x55, 0xFF, 0x55, 0x00, 0x55, 0xFF, 0xAA, 0x00, 0x55, 0xFF, 0xFF, 0x00,
105 0x00, 0x00, 0x55, 0x00, 0x80, 0x00, 0x55, 0x00, 0x00, 0x24, 0x55, 0x00,
106 0x80, 0x00, 0xFF, 0x00, 0x80, 0x24, 0x00, 0x00, 0x80, 0x24, 0x55, 0x00,
107 0x80, 0x24, 0xAA, 0x00, 0x80, 0x24, 0xFF, 0x00, 0x80, 0x49, 0x00, 0x00,
108 0x80, 0x49, 0x55, 0x00, 0x80, 0x49, 0xAA, 0x00, 0x80, 0x49, 0xFF, 0x00,
109 0x80, 0x6D, 0x00, 0x00, 0x80, 0x6D, 0x55, 0x00, 0x80, 0x6D, 0xAA, 0x00,
110 0x80, 0x6D, 0xFF, 0x00, 0x08, 0x08, 0x08, 0x00, 0x0F, 0x0F, 0x0F, 0x00,
111 0x17, 0x17, 0x17, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x27, 0x27, 0x27, 0x00,
112 0x2E, 0x2E, 0x2E, 0x00, 0x36, 0x36, 0x36, 0x00, 0x3E, 0x3E, 0x3E, 0x00,
113 0x46, 0x46, 0x46, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x55, 0x55, 0x55, 0x00,
114 0x5D, 0x5D, 0x5D, 0x00, 0x64, 0x64, 0x64, 0x00, 0x6C, 0x6C, 0x6C, 0x00,
115 0x74, 0x74, 0x74, 0x00, 0x7C, 0x7C, 0x7C, 0x00, 0xFF, 0xDB, 0x00, 0x00,
116 0x8B, 0x8B, 0x8B, 0x00, 0x93, 0x93, 0x93, 0x00, 0x9B, 0x9B, 0x9B, 0x00,
117 0xFF, 0xB6, 0xFF, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xB2, 0xB2, 0xB2, 0x00,
118 0xB9, 0xB9, 0xB9, 0x00, 0x00, 0x24, 0xFF, 0x00, 0x00, 0x49, 0x00, 0x00,
119 0xD1, 0xD1, 0xD1, 0x00, 0xD8, 0xD8, 0xD8, 0x00, 0xE0, 0xE0, 0xE0, 0x00,
120 0xE8, 0xE8, 0xE8, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xFF, 0xB6, 0xAA, 0x00,
121 0xFF, 0xDB, 0xFF, 0x00, 0x80, 0x92, 0x55, 0x00, 0x80, 0x92, 0xAA, 0x00,
122 0x80, 0x92, 0xFF, 0x00, 0x80, 0xB6, 0x00, 0x00, 0x80, 0xB6, 0x55, 0x00,
123 0x80, 0xB6, 0xAA, 0x00, 0x80, 0xB6, 0xFF, 0x00, 0x80, 0xDB, 0x00, 0x00,
124 0x80, 0xDB, 0x55, 0x00, 0x80, 0xDB, 0xAA, 0x00, 0x80, 0xDB, 0xFF, 0x00,
125 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x55, 0x00, 0x80, 0xFF, 0xAA, 0x00,
126 0x80, 0xFF, 0xFF, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x55, 0x00,
127 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x24, 0x00, 0x00,
128 0xAA, 0x24, 0x55, 0x00, 0xAA, 0x24, 0xAA, 0x00, 0xAA, 0x24, 0xFF, 0x00,
129 0xAA, 0x49, 0x00, 0x00, 0xAA, 0x49, 0x55, 0x00, 0xAA, 0x49, 0xAA, 0x00,
130 0xAA, 0x49, 0xFF, 0x00, 0xAA, 0x6D, 0x00, 0x00, 0xAA, 0x6D, 0x55, 0x00,
131 0xAA, 0x6D, 0xAA, 0x00, 0xAA, 0x6D, 0xFF, 0x00, 0xAA, 0x92, 0x00, 0x00,
132 0xAA, 0x92, 0x55, 0x00, 0xAA, 0x92, 0xAA, 0x00, 0xAA, 0x92, 0xFF, 0x00,
133 0xAA, 0xB6, 0x00, 0x00, 0xAA, 0xB6, 0x55, 0x00, 0xAA, 0xB6, 0xAA, 0x00,
134 0xAA, 0xB6, 0xFF, 0x00, 0xAA, 0xDB, 0x00, 0x00, 0xAA, 0xDB, 0x55, 0x00,
135 0xAA, 0xDB, 0xAA, 0x00, 0x00, 0x49, 0x55, 0x00, 0xAA, 0xFF, 0x00, 0x00,
136 0xAA, 0xFF, 0x55, 0x00, 0xAA, 0xFF, 0xAA, 0x00, 0xAA, 0xFF, 0xFF, 0x00,
137 0xD5, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x55, 0x00, 0xD5, 0x00, 0xAA, 0x00,
138 0xD5, 0x00, 0xFF, 0x00, 0xD5, 0x24, 0x00, 0x00, 0xD5, 0x24, 0x55, 0x00,
139 0xD5, 0x24, 0xAA, 0x00, 0xD5, 0x24, 0xFF, 0x00, 0xD5, 0x49, 0x00, 0x00,
140 0xD5, 0x49, 0x55, 0x00, 0xD5, 0x49, 0xAA, 0x00, 0xD5, 0x49, 0xFF, 0x00,
141 0xD5, 0x6D, 0x00, 0x00, 0xD5, 0x6D, 0x55, 0x00, 0xD5, 0x6D, 0xAA, 0x00,
142 0xD5, 0x6D, 0xFF, 0x00, 0xD5, 0x92, 0x00, 0x00, 0xD5, 0x92, 0x55, 0x00,
143 0xD5, 0x92, 0xAA, 0x00, 0xD5, 0x92, 0xFF, 0x00, 0xD5, 0xB6, 0x00, 0x00,
144 0xD5, 0xB6, 0x55, 0x00, 0xD5, 0xB6, 0xAA, 0x00, 0xD5, 0xB6, 0xFF, 0x00,
145 0xD5, 0xDB, 0x00, 0x00, 0xD5, 0xDB, 0x55, 0x00, 0xD5, 0xDB, 0xAA, 0x00,
146 0xD5, 0xDB, 0xFF, 0x00, 0xD5, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x55, 0x00,
147 0xD5, 0xFF, 0xAA, 0x00, 0xD5, 0xFF, 0xFF, 0x00, 0xFF, 0xDB, 0x55, 0x00,
148 0xFF, 0x00, 0x55, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0xFF, 0xFF, 0x55, 0x00,
149 0xFF, 0x24, 0x00, 0x00, 0xFF, 0x24, 0x55, 0x00, 0xFF, 0x24, 0xAA, 0x00,
150 0xFF, 0x24, 0xFF, 0x00, 0xFF, 0x49, 0x00, 0x00, 0xFF, 0x49, 0x55, 0x00,
151 0xFF, 0x49, 0xAA, 0x00, 0xFF, 0x49, 0xFF, 0x00, 0xFF, 0x6D, 0x00, 0x00,
152 0xFF, 0x6D, 0x55, 0x00, 0xFF, 0x6D, 0xAA, 0x00, 0xFF, 0x6D, 0xFF, 0x00,
153 0xFF, 0x92, 0x00, 0x00, 0xFF, 0x92, 0x55, 0x00, 0xFF, 0x92, 0xAA, 0x00,
154 0xFF, 0x92, 0xFF, 0x00, 0xFF, 0xB6, 0x00, 0x00, 0xFF, 0xB6, 0x55, 0x00,
155 0xF7, 0xF7, 0xF7, 0x00, 0xA2, 0xA2, 0xA2, 0x00, 0x83, 0x83, 0x83, 0x00,
156 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
157 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00,
158 0xFF, 0xFF, 0xFF, 0x00
164 inline sal_Int32 SwapDWord( sal_Int32 n )
166 #ifndef OSL_LITENDIAN
167 return OSL_SWAPDWORD( n );
168 #else
169 return n;
170 #endif
173 inline sal_Int16 SwapWord( sal_Int16 n )
175 #ifndef OSL_LITENDIAN
176 return OSL_SWAPWORD( n );
177 #else
178 return n;
179 #endif
183 static void WriteBMPHeader( SvStream& rStream,
184 const SvxRTFPictureType& rPicType )
186 sal_uInt32 n4Width = rPicType.nWidth;
187 sal_uInt32 n4Height = rPicType.nHeight;
188 sal_uInt16 n4ColBits = rPicType.nBitsPerPixel;
190 sal_uInt16 nColors = (1 << n4ColBits); // Number of colors (1, 16, 256)
191 sal_uInt16 nWdtOut = rPicType.nWidthBytes;
192 if( !nWdtOut )
193 nWdtOut = (sal_uInt16)((( n4Width * n4ColBits + 31 ) / 32 ) * 4 );
195 sal_Int32 nOffset = 14 + 40; // BMP_FILE_HD_SIZ + sizeof(*pBmpInfo);
196 if( 256 >= nColors )
197 nOffset += nColors * 4;
198 sal_Int32 nSize = nOffset + nWdtOut * n4Height;
199 rStream << "BM" // = "BM"
200 << SwapDWord(nSize) // Filesize in Bytes
201 << SwapWord(0) // Reserved
202 << SwapWord(0) // Reserved
203 << SwapDWord(nOffset); // Offset?
205 rStream << SwapDWord(40) // sizeof( BmpInfo )
206 << SwapDWord(n4Width)
207 << SwapDWord(n4Height)
208 << (sal_uInt16)1
209 << n4ColBits
210 << SwapDWord(0)
211 << SwapDWord(0)
212 << SwapDWord( rPicType.nGoalWidth
213 ? rPicType.nGoalWidth * 1000L / 254L
214 : 0 ) // DPI in Pixel per Meter
215 << SwapDWord( rPicType.nGoalHeight
216 ? rPicType.nGoalHeight * 1000L / 254L // dito
217 : 0 )
218 << SwapDWord(0)
219 << SwapDWord(0);
222 switch( rPicType.nBitsPerPixel )
224 case 1: rStream.Write( aPal1, sizeof( aPal1 )); break;
225 case 4: rStream.Write( aPal4, sizeof( aPal4 )); break;
226 case 8: rStream.Write( aPal8, sizeof( aPal8 )); break;
230 // Converts the ASCII characters to hexadecimal codes in binary.
231 // If invalid data is found (eg. characters outside 0-9|a-f|A-F), then
232 // USHRT_MAX is returned, else the number of converted charachters.
233 xub_StrLen SvxRTFParser::HexToBin( String& rToken )
235 // then create "Binary data" from the hex values.
236 // (missuse the String as temp Buffer)
237 if( rToken.Len() & 1 ) // odd number, fill out with 0
238 rToken += '0';
240 xub_StrLen n, nLen;
241 sal_Unicode nVal;
242 sal_Bool bValidData = sal_True;
243 const sal_Unicode* pStr = rToken.GetBufferAccess();
244 sal_Char* pData = (sal_Char*)pStr;
245 for( n = 0, nLen = rToken.Len(); n < nLen; ++n, ++pStr )
247 if( ((nVal = *pStr) >= '0') && ( nVal <= '9') )
248 nVal -= '0';
249 else if( (nVal >= 'A') && (nVal <= 'F') )
250 nVal -= 'A' - 10;
251 else if( (nVal >= 'a') && (nVal <= 'f') )
252 nVal -= 'a' - 10;
253 else
255 DBG_ASSERT( !this, "invalid Hex value" );
256 bValidData = sal_False;
257 break;
260 if( n & 1 )
261 *(pData++) |= nVal & 0x0f;
262 else
263 *(pData) = sal::static_int_cast< char >( ( nVal << 4 ) & 0xf0 );
265 // the len div 2, because 2 character are one byte
266 return bValidData ? nLen / 2 : STRING_NOTFOUND;
269 sal_Bool SvxRTFParser::ReadBmpData( Graphic& rGrf, SvxRTFPictureType& rPicType )
271 // Delete the old data
272 rGrf.Clear();
274 rtl_TextEncoding eOldEnc = GetSrcEncoding();
275 SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
277 const sal_Char* pFilterNm = 0;
278 boost::scoped_ptr<SvCacheStream> pTmpFile;
280 int nToken = 0;
281 bool bValidBmp = true, bFirstTextToken = true;
282 int _nOpenBrakets = 1, // the first was already recognized before!
283 nValidDataBraket = 1;
285 if( RTF_SHPPICT == GetStackPtr(0)->nTokenId )
286 ++nValidDataBraket;
287 OUString sShapePropertyName, sShapePropertyValue;
288 int nShapePropertyBracket = -1;
289 while( _nOpenBrakets && IsParserWorking() && bValidBmp )
291 nToken = GetNextToken();
292 sal_uInt16 nVal = sal_uInt16( nTokenValue );
293 switch( nToken )
295 case '}':
296 --_nOpenBrakets;
297 if( nShapePropertyBracket > 0 && nShapePropertyBracket > _nOpenBrakets )
299 nShapePropertyBracket = -1;
300 if( !sShapePropertyName.isEmpty() )
302 rPicType.aPropertyPairs.push_back( ::std::pair< OUString, OUString >( sShapePropertyName, sShapePropertyValue ) );
303 sShapePropertyName = sShapePropertyValue = ::rtl::OUString();
306 break;
307 case '{':
309 if( RTF_IGNOREFLAG != GetNextToken() )
310 nToken = SkipToken( -1 );
311 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
312 nToken = SkipToken( -2 );
313 else
315 // gleich herausfiltern
316 ReadUnknownData();
317 nToken = GetNextToken();
318 if( '}' != nToken )
319 eState = SVPAR_ERROR;
320 break;
322 ++_nOpenBrakets;
324 break;
326 case RTF_MACPICT:
328 rPicType.eStyle = SvxRTFPictureType::MAC_QUICKDRAW;
329 // Mac-Pict gets a empty header above
330 pTmpFile.reset(new SvCacheStream);
331 std::vector<char> a512Zeros(512, '\0');
332 pTmpFile->Write( &a512Zeros[0], a512Zeros.size() );
333 pFilterNm = "PCT";
335 break;
337 case RTF_EMFBLIP:
338 case RTF_WMETAFILE:
339 case RTF_PNGBLIP:
340 case RTF_JPEGBLIP:
341 case RTF_WBITMAP:
342 case RTF_OSMETAFILE:
343 case RTF_DIBITMAP:
345 switch( nToken )
347 case RTF_EMFBLIP:
348 rPicType.eStyle = SvxRTFPictureType::ENHANCED_MF;
349 pFilterNm = "EMF";
350 break;
351 case RTF_WMETAFILE:
352 rPicType.eStyle = SvxRTFPictureType::WIN_METAFILE;
353 pFilterNm = "WMF";
354 break;
355 case RTF_PNGBLIP:
356 rPicType.eStyle = SvxRTFPictureType::RTF_PNG;
357 pFilterNm = "PNG";
358 break;
359 case RTF_JPEGBLIP:
360 rPicType.eStyle = SvxRTFPictureType::RTF_JPG;
361 pFilterNm = "JPG";
362 break;
364 case RTF_WBITMAP:
365 rPicType.eStyle = SvxRTFPictureType::RTF_BITMAP;
366 break;
367 case RTF_OSMETAFILE:
368 rPicType.eStyle = SvxRTFPictureType::OS2_METAFILE;
369 break;
370 case RTF_DIBITMAP:
371 rPicType.eStyle = SvxRTFPictureType::RTF_DI_BMP;
372 break;
375 rPicType.nType = nVal;
376 pTmpFile.reset(new SvCacheStream);
378 break;
380 case RTF_PICW: rPicType.nWidth = nVal; break;
381 case RTF_PICH: rPicType.nHeight = nVal; break;
382 case RTF_WBMBITSPIXEL: rPicType.nBitsPerPixel = nVal; break;
383 case RTF_WBMPLANES: rPicType.nPlanes = nVal; break;
384 case RTF_WBMWIDTHBYTES: rPicType.nWidthBytes = nVal; break;
385 case RTF_PICWGOAL: rPicType.nGoalWidth = nVal; break;
386 case RTF_PICHGOAL: rPicType.nGoalHeight = nVal; break;
387 case RTF_BIN:
388 rPicType.nMode = SvxRTFPictureType::BINARY_MODE;
389 rPicType.uPicLen = nTokenValue;
390 if (rPicType.uPicLen)
392 rStrm.SeekRel(-1);
393 sal_uInt8 aData[4096];
394 sal_uInt32 nSize = sizeof(aData);
396 while (rPicType.uPicLen > 0)
398 if (rPicType.uPicLen < nSize)
399 nSize = rPicType.uPicLen;
401 rStrm.Read(aData, nSize);
402 pTmpFile->Write(aData, nSize);
403 rPicType.uPicLen -= nSize;
405 nNextCh = GetNextChar();
406 bValidBmp = !pTmpFile->GetError();
408 break;
409 case RTF_PICSCALEX: rPicType.nScalX = nVal; break;
410 case RTF_PICSCALEY: rPicType.nScalY = nVal; break;
411 case RTF_PICSCALED: break;
413 case RTF_PICCROPT: rPicType.nCropT = (short)nTokenValue; break;
414 case RTF_PICCROPB: rPicType.nCropB = (short)nTokenValue; break;
415 case RTF_PICCROPL: rPicType.nCropL = (short)nTokenValue; break;
416 case RTF_PICCROPR: rPicType.nCropR = (short)nTokenValue; break;
417 case RTF_SP:
418 //read pairs of {\sn Name}{\sv Value}
419 nShapePropertyBracket = _nOpenBrakets;
420 break;
421 case RTF_SN:
422 nToken = GetNextToken();
423 if( nToken != '}' )
424 sShapePropertyName = aToken;
425 else
426 nToken = SkipToken( -1 );
427 break;
428 case RTF_SV:
429 nToken = GetNextToken();
430 if( nToken != '}' )
431 sShapePropertyValue = aToken;
432 else
433 nToken = SkipToken( -1 );
434 break;
435 case RTF_TEXTTOKEN:
436 if( nValidDataBraket != _nOpenBrakets )
437 break;
439 if( bFirstTextToken )
441 switch( rPicType.eStyle )
443 case SvxRTFPictureType::RTF_BITMAP:
444 // first write the header and the info structure
445 if( pTmpFile )
446 ::WriteBMPHeader( *pTmpFile, rPicType );
447 break;
448 default:
449 break;
451 bFirstTextToken = sal_False;
454 if( pTmpFile && SvxRTFPictureType::HEX_MODE == rPicType.nMode )
456 xub_StrLen nTokenLen = HexToBin( aToken );
457 if( STRING_NOTFOUND == nTokenLen )
458 bValidBmp = sal_False;
459 else
461 pTmpFile->Write( (sal_Char*)aToken.GetBuffer(),
462 nTokenLen );
463 bValidBmp = 0 == pTmpFile->GetError();
466 break;
470 if (pTmpFile)
472 //#i20775#
473 if (pTmpFile->Tell() == 0)
474 bValidBmp = false;
476 if( bValidBmp )
478 GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
479 sal_uInt16 nImportFilter = GRFILTER_FORMAT_DONTKNOW;
481 if( pFilterNm )
483 String sTmp;
484 for( sal_uInt16 n = rGF.GetImportFormatCount(); n; )
486 sTmp = rGF.GetImportFormatShortName( --n );
487 if( sTmp.EqualsAscii( pFilterNm ))
489 nImportFilter = n;
490 break;
495 String sTmpStr;
496 pTmpFile->Seek( STREAM_SEEK_TO_BEGIN );
497 bValidBmp = 0 == rGF.ImportGraphic( rGrf, sTmpStr, *pTmpFile, nImportFilter );
501 if( !bValidBmp )
503 rGrf.Clear();
504 // TODO: If nToken were not initialized to 0 above, it would potentially
505 // be used uninitialized here (if IsParserWorking() is false at the
506 // start of the while loop above):
507 if( '}' != nToken )
508 SkipGroup();
510 else
512 switch( rPicType.eStyle )
514 case SvxRTFPictureType::RTF_PNG:
515 case SvxRTFPictureType::RTF_JPG:
517 const MapMode aMap( MAP_100TH_MM );
518 Size aSize( rGrf.GetPrefSize() );
519 if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
520 aSize = Application::GetDefaultDevice()->PixelToLogic(
521 aSize, aMap );
522 else
523 aSize = OutputDevice::LogicToLogic( aSize,
524 rGrf.GetPrefMapMode(), aMap );
525 rPicType.nWidth = sal::static_int_cast< sal_uInt16 >(aSize.Width());
526 rPicType.nHeight = sal::static_int_cast< sal_uInt16 >(
527 aSize.Height());
529 break;
530 default:
531 break;
534 SetSrcEncoding( eOldEnc );
536 SkipToken( -1 ); // the closing brace is evaluated "above"
537 return bValidBmp;
540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */