1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sdext.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <pdfparse.hxx>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <rtl/strbuf.hxx>
34*cdf0e10cSrcweir #include <rtl/ustring.hxx>
35*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
36*cdf0e10cSrcweir #include <rtl/alloc.h>
37*cdf0e10cSrcweir #include <rtl/digest.h>
38*cdf0e10cSrcweir #include <rtl/cipher.h>
39*cdf0e10cSrcweir #include <rtl/memory.h>
40*cdf0e10cSrcweir #ifdef SYSTEM_ZLIB
41*cdf0e10cSrcweir #include "zlib.h"
42*cdf0e10cSrcweir #else
43*cdf0e10cSrcweir #include <zlib/zlib.h>
44*cdf0e10cSrcweir #endif
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <math.h>
47*cdf0e10cSrcweir #include <map>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #include <stdio.h>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir using namespace rtl;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir namespace pdfparse
54*cdf0e10cSrcweir {
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir struct EmitImplData
57*cdf0e10cSrcweir {
58*cdf0e10cSrcweir     // xref table: maps object number to a pair of (generation, buffer offset)
59*cdf0e10cSrcweir     typedef std::map< unsigned int, std::pair< unsigned int, unsigned int > > XRefTable;
60*cdf0e10cSrcweir     XRefTable m_aXRefTable;
61*cdf0e10cSrcweir     // container of all indirect objects (usually a PDFFile*)
62*cdf0e10cSrcweir     const PDFContainer* m_pObjectContainer;
63*cdf0e10cSrcweir     unsigned int m_nDecryptObject;
64*cdf0e10cSrcweir     unsigned int m_nDecryptGeneration;
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir     // returns true if the xref table was updated
67*cdf0e10cSrcweir     bool insertXref( unsigned int nObject, unsigned int nGeneration, unsigned int nOffset )
68*cdf0e10cSrcweir     {
69*cdf0e10cSrcweir         XRefTable::iterator it = m_aXRefTable.find( nObject );
70*cdf0e10cSrcweir         if( it == m_aXRefTable.end() )
71*cdf0e10cSrcweir         {
72*cdf0e10cSrcweir             // new entry
73*cdf0e10cSrcweir             m_aXRefTable[ nObject ] = std::pair<unsigned int, unsigned int>(nGeneration,nOffset);
74*cdf0e10cSrcweir             return true;
75*cdf0e10cSrcweir         }
76*cdf0e10cSrcweir         // update old entry, if generation number is higher
77*cdf0e10cSrcweir         if( it->second.first < nGeneration )
78*cdf0e10cSrcweir         {
79*cdf0e10cSrcweir             it->second = std::pair<unsigned int, unsigned int>(nGeneration,nOffset);
80*cdf0e10cSrcweir             return true;
81*cdf0e10cSrcweir         }
82*cdf0e10cSrcweir         return false;
83*cdf0e10cSrcweir     }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir     EmitImplData( const PDFContainer* pTopContainer ) :
86*cdf0e10cSrcweir         m_pObjectContainer( pTopContainer ),
87*cdf0e10cSrcweir         m_nDecryptObject( 0 ),
88*cdf0e10cSrcweir         m_nDecryptGeneration( 0 )
89*cdf0e10cSrcweir     {}
90*cdf0e10cSrcweir     ~EmitImplData() {}
91*cdf0e10cSrcweir     bool decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
92*cdf0e10cSrcweir                   unsigned int nObject, unsigned int nGeneration ) const
93*cdf0e10cSrcweir     {
94*cdf0e10cSrcweir         const PDFFile* pFile = dynamic_cast<const PDFFile*>(m_pObjectContainer);
95*cdf0e10cSrcweir         return pFile ? pFile->decrypt( pInBuffer, nLen, pOutBuffer, nObject, nGeneration ) : false;
96*cdf0e10cSrcweir     }
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir     void setDecryptObject( unsigned int nObject, unsigned int nGeneration )
99*cdf0e10cSrcweir     {
100*cdf0e10cSrcweir         m_nDecryptObject = nObject;
101*cdf0e10cSrcweir         m_nDecryptGeneration = nGeneration;
102*cdf0e10cSrcweir     }
103*cdf0e10cSrcweir };
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir using namespace pdfparse;
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir EmitContext::EmitContext( const PDFContainer* pTop ) :
110*cdf0e10cSrcweir     m_bDeflate( false ),
111*cdf0e10cSrcweir     m_bDecrypt( false ),
112*cdf0e10cSrcweir     m_pImplData( NULL )
113*cdf0e10cSrcweir {
114*cdf0e10cSrcweir     if( pTop )
115*cdf0e10cSrcweir         m_pImplData = new EmitImplData( pTop );
116*cdf0e10cSrcweir }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir EmitContext::~EmitContext()
119*cdf0e10cSrcweir {
120*cdf0e10cSrcweir     delete m_pImplData;
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir PDFEntry::~PDFEntry()
124*cdf0e10cSrcweir {
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir EmitImplData* PDFEntry::getEmitData( EmitContext& rContext ) const
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir     return rContext.m_pImplData;
130*cdf0e10cSrcweir }
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir void PDFEntry::setEmitData( EmitContext& rContext, EmitImplData* pNewEmitData ) const
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir     if( rContext.m_pImplData && rContext.m_pImplData != pNewEmitData )
135*cdf0e10cSrcweir         delete rContext.m_pImplData;
136*cdf0e10cSrcweir     rContext.m_pImplData = pNewEmitData;
137*cdf0e10cSrcweir }
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir PDFValue::~PDFValue()
140*cdf0e10cSrcweir {
141*cdf0e10cSrcweir }
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir PDFComment::~PDFComment()
144*cdf0e10cSrcweir {
145*cdf0e10cSrcweir }
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir bool PDFComment::emit( EmitContext& rWriteContext ) const
148*cdf0e10cSrcweir {
149*cdf0e10cSrcweir     return rWriteContext.write( m_aComment.getStr(), m_aComment.getLength() );
150*cdf0e10cSrcweir }
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir PDFEntry* PDFComment::clone() const
153*cdf0e10cSrcweir {
154*cdf0e10cSrcweir     return new PDFComment( m_aComment );
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir PDFName::~PDFName()
158*cdf0e10cSrcweir {
159*cdf0e10cSrcweir }
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir bool PDFName::emit( EmitContext& rWriteContext ) const
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     if( ! rWriteContext.write( " /", 2 ) )
164*cdf0e10cSrcweir         return false;
165*cdf0e10cSrcweir     return rWriteContext.write( m_aName.getStr(), m_aName.getLength() );
166*cdf0e10cSrcweir }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir PDFEntry* PDFName::clone() const
169*cdf0e10cSrcweir {
170*cdf0e10cSrcweir     return new PDFName( m_aName );
171*cdf0e10cSrcweir }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir OUString PDFName::getFilteredName() const
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir     OStringBuffer aFilter( m_aName.getLength() );
176*cdf0e10cSrcweir     const sal_Char* pStr = m_aName.getStr();
177*cdf0e10cSrcweir     unsigned int nLen = m_aName.getLength();
178*cdf0e10cSrcweir     for( unsigned int i = 0; i < nLen; i++ )
179*cdf0e10cSrcweir     {
180*cdf0e10cSrcweir         if( pStr[i] == '#' && i < nLen - 3 )
181*cdf0e10cSrcweir         {
182*cdf0e10cSrcweir             sal_Char rResult = 0;
183*cdf0e10cSrcweir             i++;
184*cdf0e10cSrcweir             if( pStr[i] >= '0' && pStr[i] <= '9' )
185*cdf0e10cSrcweir                 rResult = sal_Char( pStr[i]-'0' ) << 4;
186*cdf0e10cSrcweir             else if( pStr[i] >= 'a' && pStr[i] <= 'f' )
187*cdf0e10cSrcweir                 rResult = sal_Char( pStr[i]-'a' + 10 ) << 4;
188*cdf0e10cSrcweir             else if( pStr[i] >= 'A' && pStr[i] <= 'F' )
189*cdf0e10cSrcweir                 rResult = sal_Char( pStr[i]-'A' + 10 ) << 4;
190*cdf0e10cSrcweir             i++;
191*cdf0e10cSrcweir             if( pStr[i] >= '0' && pStr[i] <= '9' )
192*cdf0e10cSrcweir                 rResult |= sal_Char( pStr[i]-'0' );
193*cdf0e10cSrcweir             else if( pStr[i] >= 'a' && pStr[i] <= 'f' )
194*cdf0e10cSrcweir                 rResult |= sal_Char( pStr[i]-'a' + 10 );
195*cdf0e10cSrcweir             else if( pStr[i] >= 'A' && pStr[i] <= 'F' )
196*cdf0e10cSrcweir                 rResult |= sal_Char( pStr[i]-'A' + 10 );
197*cdf0e10cSrcweir             aFilter.append( rResult );
198*cdf0e10cSrcweir         }
199*cdf0e10cSrcweir         else
200*cdf0e10cSrcweir             aFilter.append( pStr[i] );
201*cdf0e10cSrcweir     }
202*cdf0e10cSrcweir     return OStringToOUString( aFilter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir PDFString::~PDFString()
206*cdf0e10cSrcweir {
207*cdf0e10cSrcweir }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir bool PDFString::emit( EmitContext& rWriteContext ) const
210*cdf0e10cSrcweir {
211*cdf0e10cSrcweir     if( ! rWriteContext.write( " ", 1 ) )
212*cdf0e10cSrcweir         return false;
213*cdf0e10cSrcweir     EmitImplData* pEData = getEmitData( rWriteContext );
214*cdf0e10cSrcweir     if( rWriteContext.m_bDecrypt && pEData && pEData->m_nDecryptObject )
215*cdf0e10cSrcweir     {
216*cdf0e10cSrcweir         OString aFiltered( getFilteredString() );
217*cdf0e10cSrcweir         // decrypt inplace (evil since OString is supposed to be const
218*cdf0e10cSrcweir         // however in this case we know that getFilteredString returned a singular string instance
219*cdf0e10cSrcweir         pEData->decrypt( (sal_uInt8*)aFiltered.getStr(), aFiltered.getLength(),
220*cdf0e10cSrcweir                          (sal_uInt8*)aFiltered.getStr(),
221*cdf0e10cSrcweir                          pEData->m_nDecryptObject, pEData->m_nDecryptGeneration );
222*cdf0e10cSrcweir         // check for string or hex string
223*cdf0e10cSrcweir         const sal_Char* pStr = aFiltered.getStr();
224*cdf0e10cSrcweir         if( aFiltered.getLength() > 1 &&
225*cdf0e10cSrcweir            ( (pStr[0] == sal_Char(0xff) && pStr[1] == sal_Char(0xfe)) ||
226*cdf0e10cSrcweir              (pStr[0] == sal_Char(0xfe) && pStr[1] == sal_Char(0xff)) ) )
227*cdf0e10cSrcweir         {
228*cdf0e10cSrcweir             static const char pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
229*cdf0e10cSrcweir                                               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
230*cdf0e10cSrcweir             if( ! rWriteContext.write( "<", 1 ) )
231*cdf0e10cSrcweir                 return false;
232*cdf0e10cSrcweir             for( sal_Int32 i = 0; i < aFiltered.getLength(); i++ )
233*cdf0e10cSrcweir             {
234*cdf0e10cSrcweir                 if( ! rWriteContext.write( pHexTab + ((sal_uInt32(pStr[i]) >> 4) & 0x0f), 1 ) )
235*cdf0e10cSrcweir                     return false;
236*cdf0e10cSrcweir                 if( ! rWriteContext.write( pHexTab + (sal_uInt32(pStr[i]) & 0x0f), 1 ) )
237*cdf0e10cSrcweir                     return false;
238*cdf0e10cSrcweir             }
239*cdf0e10cSrcweir             if( ! rWriteContext.write( ">", 1 ) )
240*cdf0e10cSrcweir                 return false;
241*cdf0e10cSrcweir         }
242*cdf0e10cSrcweir         else
243*cdf0e10cSrcweir         {
244*cdf0e10cSrcweir             if( ! rWriteContext.write( "(", 1 ) )
245*cdf0e10cSrcweir                 return false;
246*cdf0e10cSrcweir             if( ! rWriteContext.write( aFiltered.getStr(), aFiltered.getLength() ) )
247*cdf0e10cSrcweir                 return false;
248*cdf0e10cSrcweir             if( ! rWriteContext.write( ")", 1 ) )
249*cdf0e10cSrcweir                 return false;
250*cdf0e10cSrcweir         }
251*cdf0e10cSrcweir         return true;
252*cdf0e10cSrcweir     }
253*cdf0e10cSrcweir     return rWriteContext.write( m_aString.getStr(), m_aString.getLength() );
254*cdf0e10cSrcweir }
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir PDFEntry* PDFString::clone() const
257*cdf0e10cSrcweir {
258*cdf0e10cSrcweir     return new PDFString( m_aString );
259*cdf0e10cSrcweir }
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir OString PDFString::getFilteredString() const
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir     int nLen = m_aString.getLength();
264*cdf0e10cSrcweir     OStringBuffer aBuf( nLen );
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir     const sal_Char* pStr = m_aString.getStr();
267*cdf0e10cSrcweir     if( *pStr == '(' )
268*cdf0e10cSrcweir     {
269*cdf0e10cSrcweir         const sal_Char* pRun = pStr+1;
270*cdf0e10cSrcweir         while( pRun - pStr < nLen-1 )
271*cdf0e10cSrcweir         {
272*cdf0e10cSrcweir             if( *pRun == '\\' )
273*cdf0e10cSrcweir             {
274*cdf0e10cSrcweir                 pRun++;
275*cdf0e10cSrcweir                 if( pRun - pStr < nLen )
276*cdf0e10cSrcweir                 {
277*cdf0e10cSrcweir                     sal_Char aEsc = 0;
278*cdf0e10cSrcweir                     if( *pRun == 'n' )
279*cdf0e10cSrcweir                         aEsc = '\n';
280*cdf0e10cSrcweir                     else if( *pRun == 'r' )
281*cdf0e10cSrcweir                         aEsc = '\r';
282*cdf0e10cSrcweir                     else if( *pRun == 't' )
283*cdf0e10cSrcweir                         aEsc = '\t';
284*cdf0e10cSrcweir                     else if( *pRun == 'b' )
285*cdf0e10cSrcweir                         aEsc = '\b';
286*cdf0e10cSrcweir                     else if( *pRun == 'f' )
287*cdf0e10cSrcweir                         aEsc = '\f';
288*cdf0e10cSrcweir                     else if( *pRun == '(' )
289*cdf0e10cSrcweir                         aEsc = '(';
290*cdf0e10cSrcweir                     else if( *pRun == ')' )
291*cdf0e10cSrcweir                         aEsc = ')';
292*cdf0e10cSrcweir                     else if( *pRun == '\\' )
293*cdf0e10cSrcweir                         aEsc = '\\';
294*cdf0e10cSrcweir                     else if( *pRun == '\n' )
295*cdf0e10cSrcweir                     {
296*cdf0e10cSrcweir                         pRun++;
297*cdf0e10cSrcweir                         continue;
298*cdf0e10cSrcweir                     }
299*cdf0e10cSrcweir                     else if( *pRun == '\r' )
300*cdf0e10cSrcweir                     {
301*cdf0e10cSrcweir                         pRun++;
302*cdf0e10cSrcweir                         if( *pRun == '\n' )
303*cdf0e10cSrcweir                             pRun++;
304*cdf0e10cSrcweir                         continue;
305*cdf0e10cSrcweir                     }
306*cdf0e10cSrcweir                     else
307*cdf0e10cSrcweir                     {
308*cdf0e10cSrcweir                         int i = 0;
309*cdf0e10cSrcweir                         while( i++ < 3 && *pRun >= '0' && *pRun <= '7' )
310*cdf0e10cSrcweir                             aEsc = 8*aEsc + (*pRun++ - '0');
311*cdf0e10cSrcweir                         // move pointer back to last character of octal sequence
312*cdf0e10cSrcweir                         pRun--;
313*cdf0e10cSrcweir                     }
314*cdf0e10cSrcweir                     aBuf.append( aEsc );
315*cdf0e10cSrcweir                 }
316*cdf0e10cSrcweir             }
317*cdf0e10cSrcweir             else
318*cdf0e10cSrcweir                 aBuf.append( *pRun );
319*cdf0e10cSrcweir             // move pointer to next character
320*cdf0e10cSrcweir             pRun++;
321*cdf0e10cSrcweir         }
322*cdf0e10cSrcweir     }
323*cdf0e10cSrcweir     else if( *pStr == '<' )
324*cdf0e10cSrcweir     {
325*cdf0e10cSrcweir         const sal_Char* pRun = pStr+1;
326*cdf0e10cSrcweir         while( *pRun != '>' && pRun - pStr < nLen )
327*cdf0e10cSrcweir         {
328*cdf0e10cSrcweir             sal_Char rResult = 0;
329*cdf0e10cSrcweir             if( *pRun >= '0' && *pRun <= '9' )
330*cdf0e10cSrcweir                 rResult = sal_Char( *pRun-'0' ) << 4;
331*cdf0e10cSrcweir             else if( *pRun >= 'a' && *pRun <= 'f' )
332*cdf0e10cSrcweir                 rResult = sal_Char( *pRun-'a' + 10 ) << 4;
333*cdf0e10cSrcweir             else if( *pRun >= 'A' && *pRun <= 'F' )
334*cdf0e10cSrcweir                 rResult = sal_Char( *pRun-'A' + 10 ) << 4;
335*cdf0e10cSrcweir             pRun++;
336*cdf0e10cSrcweir             if( *pRun != '>' && pRun - pStr < nLen )
337*cdf0e10cSrcweir             {
338*cdf0e10cSrcweir                 if( *pRun >= '0' && *pRun <= '9' )
339*cdf0e10cSrcweir                     rResult |= sal_Char( *pRun-'0' );
340*cdf0e10cSrcweir                 else if( *pRun >= 'a' && *pRun <= 'f' )
341*cdf0e10cSrcweir                     rResult |= sal_Char( *pRun-'a' + 10 );
342*cdf0e10cSrcweir                 else if( *pRun >= 'A' && *pRun <= 'F' )
343*cdf0e10cSrcweir                     rResult |= sal_Char( *pRun-'A' + 10 );
344*cdf0e10cSrcweir             }
345*cdf0e10cSrcweir             pRun++;
346*cdf0e10cSrcweir             aBuf.append( rResult );
347*cdf0e10cSrcweir         }
348*cdf0e10cSrcweir     }
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     return aBuf.makeStringAndClear();
351*cdf0e10cSrcweir }
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir PDFNumber::~PDFNumber()
354*cdf0e10cSrcweir {
355*cdf0e10cSrcweir }
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir bool PDFNumber::emit( EmitContext& rWriteContext ) const
358*cdf0e10cSrcweir {
359*cdf0e10cSrcweir     rtl::OStringBuffer aBuf( 32 );
360*cdf0e10cSrcweir     aBuf.append( ' ' );
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir     double fValue = m_fValue;
363*cdf0e10cSrcweir     bool bNeg = false;
364*cdf0e10cSrcweir     int nPrecision = 5;
365*cdf0e10cSrcweir     if( fValue < 0.0 )
366*cdf0e10cSrcweir     {
367*cdf0e10cSrcweir         bNeg = true;
368*cdf0e10cSrcweir         fValue=-fValue;
369*cdf0e10cSrcweir     }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir     sal_Int64 nInt = (sal_Int64)fValue;
372*cdf0e10cSrcweir     fValue -= (double)nInt;
373*cdf0e10cSrcweir     // optimizing hardware may lead to a value of 1.0 after the subtraction
374*cdf0e10cSrcweir     if( fValue == 1.0 || log10( 1.0-fValue ) <= -nPrecision )
375*cdf0e10cSrcweir     {
376*cdf0e10cSrcweir         nInt++;
377*cdf0e10cSrcweir         fValue = 0.0;
378*cdf0e10cSrcweir     }
379*cdf0e10cSrcweir     sal_Int64 nFrac = 0;
380*cdf0e10cSrcweir     if( fValue )
381*cdf0e10cSrcweir     {
382*cdf0e10cSrcweir         fValue *= pow( 10.0, (double)nPrecision );
383*cdf0e10cSrcweir         nFrac = (sal_Int64)fValue;
384*cdf0e10cSrcweir     }
385*cdf0e10cSrcweir     if( bNeg && ( nInt || nFrac ) )
386*cdf0e10cSrcweir         aBuf.append( '-' );
387*cdf0e10cSrcweir     aBuf.append( nInt );
388*cdf0e10cSrcweir     if( nFrac )
389*cdf0e10cSrcweir     {
390*cdf0e10cSrcweir 		int i;
391*cdf0e10cSrcweir         aBuf.append( '.' );
392*cdf0e10cSrcweir 		sal_Int64 nBound = (sal_Int64)(pow( 10.0, nPrecision - 1.0 )+0.5);
393*cdf0e10cSrcweir 		for ( i = 0; ( i < nPrecision ) && nFrac; i++ )
394*cdf0e10cSrcweir 		{
395*cdf0e10cSrcweir 			sal_Int64 nNumb = nFrac / nBound;
396*cdf0e10cSrcweir 			nFrac -= nNumb * nBound;
397*cdf0e10cSrcweir 			aBuf.append( nNumb );
398*cdf0e10cSrcweir 			nBound /= 10;
399*cdf0e10cSrcweir 		}
400*cdf0e10cSrcweir     }
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir     return rWriteContext.write( aBuf.getStr(), aBuf.getLength() );
403*cdf0e10cSrcweir }
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir PDFEntry* PDFNumber::clone() const
406*cdf0e10cSrcweir {
407*cdf0e10cSrcweir     return new PDFNumber( m_fValue );
408*cdf0e10cSrcweir }
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir PDFBool::~PDFBool()
412*cdf0e10cSrcweir {
413*cdf0e10cSrcweir }
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir bool PDFBool::emit( EmitContext& rWriteContext ) const
416*cdf0e10cSrcweir {
417*cdf0e10cSrcweir     return m_bValue ? rWriteContext.write( " true", 5 ) : rWriteContext.write( " false", 6 );
418*cdf0e10cSrcweir }
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir PDFEntry* PDFBool::clone() const
421*cdf0e10cSrcweir {
422*cdf0e10cSrcweir     return new PDFBool( m_bValue );
423*cdf0e10cSrcweir }
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir PDFNull::~PDFNull()
426*cdf0e10cSrcweir {
427*cdf0e10cSrcweir }
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir bool PDFNull::emit( EmitContext& rWriteContext ) const
430*cdf0e10cSrcweir {
431*cdf0e10cSrcweir     return rWriteContext.write( " null", 5 );
432*cdf0e10cSrcweir }
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir PDFEntry* PDFNull::clone() const
435*cdf0e10cSrcweir {
436*cdf0e10cSrcweir     return new PDFNull();
437*cdf0e10cSrcweir }
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir PDFObjectRef::~PDFObjectRef()
441*cdf0e10cSrcweir {
442*cdf0e10cSrcweir }
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir bool PDFObjectRef::emit( EmitContext& rWriteContext ) const
445*cdf0e10cSrcweir {
446*cdf0e10cSrcweir     OStringBuffer aBuf( 16 );
447*cdf0e10cSrcweir     aBuf.append( ' ' );
448*cdf0e10cSrcweir     aBuf.append( sal_Int32( m_nNumber ) );
449*cdf0e10cSrcweir     aBuf.append( ' ' );
450*cdf0e10cSrcweir     aBuf.append( sal_Int32( m_nGeneration ) );
451*cdf0e10cSrcweir     aBuf.append( " R", 2 );
452*cdf0e10cSrcweir     return rWriteContext.write( aBuf.getStr(), aBuf.getLength() );
453*cdf0e10cSrcweir }
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir PDFEntry* PDFObjectRef::clone() const
456*cdf0e10cSrcweir {
457*cdf0e10cSrcweir     return new PDFObjectRef( m_nNumber, m_nGeneration );
458*cdf0e10cSrcweir }
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir PDFContainer::~PDFContainer()
461*cdf0e10cSrcweir {
462*cdf0e10cSrcweir     int nEle = m_aSubElements.size();
463*cdf0e10cSrcweir     for( int i = 0; i < nEle; i++ )
464*cdf0e10cSrcweir         delete m_aSubElements[i];
465*cdf0e10cSrcweir }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir bool PDFContainer::emitSubElements( EmitContext& rWriteContext ) const
468*cdf0e10cSrcweir {
469*cdf0e10cSrcweir     int nEle = m_aSubElements.size();
470*cdf0e10cSrcweir     for( int i = 0; i < nEle; i++ )
471*cdf0e10cSrcweir     {
472*cdf0e10cSrcweir         if( rWriteContext.m_bDecrypt )
473*cdf0e10cSrcweir         {
474*cdf0e10cSrcweir             const PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
475*cdf0e10cSrcweir             if( pName && pName->m_aName.equals( rtl::OString("Encrypt") ) )
476*cdf0e10cSrcweir             {
477*cdf0e10cSrcweir                 i++;
478*cdf0e10cSrcweir                 continue;
479*cdf0e10cSrcweir             }
480*cdf0e10cSrcweir         }
481*cdf0e10cSrcweir         if( ! m_aSubElements[i]->emit( rWriteContext ) )
482*cdf0e10cSrcweir             return false;
483*cdf0e10cSrcweir     }
484*cdf0e10cSrcweir     return true;
485*cdf0e10cSrcweir }
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir void PDFContainer::cloneSubElements( std::vector<PDFEntry*>& rNewSubElements ) const
488*cdf0e10cSrcweir {
489*cdf0e10cSrcweir     int nEle = m_aSubElements.size();
490*cdf0e10cSrcweir     for( int i = 0; i < nEle; i++ )
491*cdf0e10cSrcweir         rNewSubElements.push_back( m_aSubElements[i]->clone() );
492*cdf0e10cSrcweir }
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir PDFObject* PDFContainer::findObject( unsigned int nNumber, unsigned int nGeneration ) const
495*cdf0e10cSrcweir {
496*cdf0e10cSrcweir     unsigned int nEle = m_aSubElements.size();
497*cdf0e10cSrcweir     for( unsigned int i = 0; i < nEle; i++ )
498*cdf0e10cSrcweir     {
499*cdf0e10cSrcweir         PDFObject* pObject = dynamic_cast<PDFObject*>(m_aSubElements[i]);
500*cdf0e10cSrcweir         if( pObject &&
501*cdf0e10cSrcweir             pObject->m_nNumber == nNumber &&
502*cdf0e10cSrcweir             pObject->m_nGeneration == nGeneration )
503*cdf0e10cSrcweir         {
504*cdf0e10cSrcweir             return pObject;
505*cdf0e10cSrcweir         }
506*cdf0e10cSrcweir     }
507*cdf0e10cSrcweir     return NULL;
508*cdf0e10cSrcweir }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir PDFArray::~PDFArray()
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir bool PDFArray::emit( EmitContext& rWriteContext ) const
515*cdf0e10cSrcweir {
516*cdf0e10cSrcweir     if( ! rWriteContext.write( "[", 1 ) )
517*cdf0e10cSrcweir         return false;
518*cdf0e10cSrcweir     if( ! emitSubElements( rWriteContext ) )
519*cdf0e10cSrcweir         return false;
520*cdf0e10cSrcweir     return rWriteContext.write( "]", 1 );
521*cdf0e10cSrcweir }
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir PDFEntry* PDFArray::clone() const
524*cdf0e10cSrcweir {
525*cdf0e10cSrcweir     PDFArray* pNewAr = new PDFArray();
526*cdf0e10cSrcweir     cloneSubElements( pNewAr->m_aSubElements );
527*cdf0e10cSrcweir     return pNewAr;
528*cdf0e10cSrcweir }
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir PDFDict::~PDFDict()
531*cdf0e10cSrcweir {
532*cdf0e10cSrcweir }
533*cdf0e10cSrcweir 
534*cdf0e10cSrcweir bool PDFDict::emit( EmitContext& rWriteContext ) const
535*cdf0e10cSrcweir {
536*cdf0e10cSrcweir     if( ! rWriteContext.write( "<<\n", 3 ) )
537*cdf0e10cSrcweir         return false;
538*cdf0e10cSrcweir     if( ! emitSubElements( rWriteContext ) )
539*cdf0e10cSrcweir         return false;
540*cdf0e10cSrcweir     return rWriteContext.write( "\n>>\n", 4 );
541*cdf0e10cSrcweir }
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir void PDFDict::insertValue( const OString& rName, PDFEntry* pValue )
544*cdf0e10cSrcweir {
545*cdf0e10cSrcweir     if( ! pValue )
546*cdf0e10cSrcweir         eraseValue( rName );
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir     std::hash_map<OString,PDFEntry*,OStringHash>::iterator it = m_aMap.find( rName );
549*cdf0e10cSrcweir     if( it == m_aMap.end() )
550*cdf0e10cSrcweir     {
551*cdf0e10cSrcweir         // new name/value, pair, append it
552*cdf0e10cSrcweir         m_aSubElements.push_back( new PDFName( rName ) );
553*cdf0e10cSrcweir         m_aSubElements.push_back( pValue );
554*cdf0e10cSrcweir     }
555*cdf0e10cSrcweir     else
556*cdf0e10cSrcweir     {
557*cdf0e10cSrcweir         unsigned int nSub = m_aSubElements.size();
558*cdf0e10cSrcweir         for( unsigned int i = 0; i < nSub; i++ )
559*cdf0e10cSrcweir             if( m_aSubElements[i] == it->second )
560*cdf0e10cSrcweir                 m_aSubElements[i] = pValue;
561*cdf0e10cSrcweir         delete it->second;
562*cdf0e10cSrcweir     }
563*cdf0e10cSrcweir     m_aMap[ rName ] = pValue;
564*cdf0e10cSrcweir }
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir void PDFDict::eraseValue( const OString& rName )
567*cdf0e10cSrcweir {
568*cdf0e10cSrcweir     unsigned int nEle = m_aSubElements.size();
569*cdf0e10cSrcweir     for( unsigned int i = 0; i < nEle; i++ )
570*cdf0e10cSrcweir     {
571*cdf0e10cSrcweir         PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
572*cdf0e10cSrcweir         if( pName && pName->m_aName.equals( rName ) )
573*cdf0e10cSrcweir         {
574*cdf0e10cSrcweir             for( unsigned int j = i+1; j < nEle; j++ )
575*cdf0e10cSrcweir             {
576*cdf0e10cSrcweir                 if( dynamic_cast<PDFComment*>(m_aSubElements[j]) == NULL )
577*cdf0e10cSrcweir                 {
578*cdf0e10cSrcweir                     // free name and value
579*cdf0e10cSrcweir                     delete m_aSubElements[j];
580*cdf0e10cSrcweir                     delete m_aSubElements[i];
581*cdf0e10cSrcweir                     // remove subelements from vector
582*cdf0e10cSrcweir                     m_aSubElements.erase( m_aSubElements.begin()+j );
583*cdf0e10cSrcweir                     m_aSubElements.erase( m_aSubElements.begin()+i );
584*cdf0e10cSrcweir                     buildMap();
585*cdf0e10cSrcweir                     return;
586*cdf0e10cSrcweir                 }
587*cdf0e10cSrcweir             }
588*cdf0e10cSrcweir         }
589*cdf0e10cSrcweir     }
590*cdf0e10cSrcweir }
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir PDFEntry* PDFDict::buildMap()
593*cdf0e10cSrcweir {
594*cdf0e10cSrcweir     // clear map
595*cdf0e10cSrcweir     m_aMap.clear();
596*cdf0e10cSrcweir     // build map
597*cdf0e10cSrcweir     unsigned int nEle = m_aSubElements.size();
598*cdf0e10cSrcweir     PDFName* pName = NULL;
599*cdf0e10cSrcweir     for( unsigned int i = 0; i < nEle; i++ )
600*cdf0e10cSrcweir     {
601*cdf0e10cSrcweir         if( dynamic_cast<PDFComment*>(m_aSubElements[i]) == NULL )
602*cdf0e10cSrcweir         {
603*cdf0e10cSrcweir             if( pName )
604*cdf0e10cSrcweir             {
605*cdf0e10cSrcweir                 m_aMap[ pName->m_aName ] = m_aSubElements[i];
606*cdf0e10cSrcweir                 pName = NULL;
607*cdf0e10cSrcweir             }
608*cdf0e10cSrcweir             else if( (pName = dynamic_cast<PDFName*>(m_aSubElements[i])) == NULL )
609*cdf0e10cSrcweir                 return m_aSubElements[i];
610*cdf0e10cSrcweir         }
611*cdf0e10cSrcweir     }
612*cdf0e10cSrcweir     return pName;
613*cdf0e10cSrcweir }
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir PDFEntry* PDFDict::clone() const
616*cdf0e10cSrcweir {
617*cdf0e10cSrcweir     PDFDict* pNewDict = new PDFDict();
618*cdf0e10cSrcweir     cloneSubElements( pNewDict->m_aSubElements );
619*cdf0e10cSrcweir     pNewDict->buildMap();
620*cdf0e10cSrcweir     return pNewDict;
621*cdf0e10cSrcweir }
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir PDFStream::~PDFStream()
624*cdf0e10cSrcweir {
625*cdf0e10cSrcweir }
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir bool PDFStream::emit( EmitContext& rWriteContext ) const
628*cdf0e10cSrcweir {
629*cdf0e10cSrcweir     return rWriteContext.copyOrigBytes( m_nBeginOffset, m_nEndOffset-m_nBeginOffset );
630*cdf0e10cSrcweir }
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir PDFEntry* PDFStream::clone() const
633*cdf0e10cSrcweir {
634*cdf0e10cSrcweir     return new PDFStream( m_nBeginOffset, m_nEndOffset, NULL );
635*cdf0e10cSrcweir }
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir unsigned int PDFStream::getDictLength( const PDFContainer* pContainer ) const
638*cdf0e10cSrcweir {
639*cdf0e10cSrcweir     if( ! m_pDict )
640*cdf0e10cSrcweir         return 0;
641*cdf0e10cSrcweir     // find /Length entry, can either be a direct or indirect number object
642*cdf0e10cSrcweir     std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
643*cdf0e10cSrcweir         m_pDict->m_aMap.find( "Length" );
644*cdf0e10cSrcweir     if( it == m_pDict->m_aMap.end() )
645*cdf0e10cSrcweir         return 0;
646*cdf0e10cSrcweir     PDFNumber* pNum = dynamic_cast<PDFNumber*>(it->second);
647*cdf0e10cSrcweir     if( ! pNum && pContainer )
648*cdf0e10cSrcweir     {
649*cdf0e10cSrcweir         PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(it->second);
650*cdf0e10cSrcweir         if( pRef )
651*cdf0e10cSrcweir         {
652*cdf0e10cSrcweir             int nEle = pContainer->m_aSubElements.size();
653*cdf0e10cSrcweir             for( int i = 0; i < nEle && ! pNum; i++ )
654*cdf0e10cSrcweir             {
655*cdf0e10cSrcweir                 PDFObject* pObj = dynamic_cast<PDFObject*>(pContainer->m_aSubElements[i]);
656*cdf0e10cSrcweir                 if( pObj &&
657*cdf0e10cSrcweir                     pObj->m_nNumber == pRef->m_nNumber &&
658*cdf0e10cSrcweir                     pObj->m_nGeneration == pRef->m_nGeneration )
659*cdf0e10cSrcweir                 {
660*cdf0e10cSrcweir                     if( pObj->m_pObject )
661*cdf0e10cSrcweir                         pNum = dynamic_cast<PDFNumber*>(pObj->m_pObject);
662*cdf0e10cSrcweir                     break;
663*cdf0e10cSrcweir                 }
664*cdf0e10cSrcweir             }
665*cdf0e10cSrcweir         }
666*cdf0e10cSrcweir     }
667*cdf0e10cSrcweir     return pNum ? static_cast<unsigned int>(pNum->m_fValue) : 0;
668*cdf0e10cSrcweir }
669*cdf0e10cSrcweir 
670*cdf0e10cSrcweir PDFObject::~PDFObject()
671*cdf0e10cSrcweir {
672*cdf0e10cSrcweir }
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir bool PDFObject::getDeflatedStream( char** ppStream, unsigned int* pBytes, const PDFContainer* pObjectContainer, EmitContext& rContext ) const
675*cdf0e10cSrcweir {
676*cdf0e10cSrcweir     bool bIsDeflated = false;
677*cdf0e10cSrcweir     if( m_pStream && m_pStream->m_pDict &&
678*cdf0e10cSrcweir         m_pStream->m_nEndOffset > m_pStream->m_nBeginOffset+15
679*cdf0e10cSrcweir         )
680*cdf0e10cSrcweir     {
681*cdf0e10cSrcweir         unsigned int nOuterStreamLen = m_pStream->m_nEndOffset - m_pStream->m_nBeginOffset;
682*cdf0e10cSrcweir         *ppStream = static_cast<char*>(rtl_allocateMemory( nOuterStreamLen ));
683*cdf0e10cSrcweir         if( ! ppStream )
684*cdf0e10cSrcweir         {
685*cdf0e10cSrcweir             *pBytes = 0;
686*cdf0e10cSrcweir             return false;
687*cdf0e10cSrcweir         }
688*cdf0e10cSrcweir         unsigned int nRead = rContext.readOrigBytes( m_pStream->m_nBeginOffset, nOuterStreamLen, *ppStream );
689*cdf0e10cSrcweir         if( nRead != nOuterStreamLen )
690*cdf0e10cSrcweir         {
691*cdf0e10cSrcweir             rtl_freeMemory( *ppStream );
692*cdf0e10cSrcweir             *ppStream = NULL;
693*cdf0e10cSrcweir             *pBytes = 0;
694*cdf0e10cSrcweir             return false;
695*cdf0e10cSrcweir         }
696*cdf0e10cSrcweir         // is there a filter entry ?
697*cdf0e10cSrcweir         std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
698*cdf0e10cSrcweir             m_pStream->m_pDict->m_aMap.find( "Filter" );
699*cdf0e10cSrcweir         if( it != m_pStream->m_pDict->m_aMap.end() )
700*cdf0e10cSrcweir         {
701*cdf0e10cSrcweir             PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
702*cdf0e10cSrcweir             if( ! pFilter )
703*cdf0e10cSrcweir             {
704*cdf0e10cSrcweir                 PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
705*cdf0e10cSrcweir                 if( pArray && ! pArray->m_aSubElements.empty() )
706*cdf0e10cSrcweir                 {
707*cdf0e10cSrcweir                     pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
708*cdf0e10cSrcweir                 }
709*cdf0e10cSrcweir             }
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir             // is the (first) filter FlateDecode ?
712*cdf0e10cSrcweir             if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
713*cdf0e10cSrcweir             {
714*cdf0e10cSrcweir                 bIsDeflated = true;
715*cdf0e10cSrcweir             }
716*cdf0e10cSrcweir         }
717*cdf0e10cSrcweir         // prepare compressed data section
718*cdf0e10cSrcweir         char* pStream = *ppStream;
719*cdf0e10cSrcweir         if( pStream[0] == 's' )
720*cdf0e10cSrcweir             pStream += 6; // skip "stream"
721*cdf0e10cSrcweir         // skip line end after "stream"
722*cdf0e10cSrcweir         while( *pStream == '\r' || *pStream == '\n' )
723*cdf0e10cSrcweir             pStream++;
724*cdf0e10cSrcweir         // get the compressed length
725*cdf0e10cSrcweir         *pBytes = m_pStream->getDictLength( pObjectContainer );
726*cdf0e10cSrcweir         if( pStream != *ppStream )
727*cdf0e10cSrcweir             rtl_moveMemory( *ppStream, pStream, *pBytes );
728*cdf0e10cSrcweir         if( rContext.m_bDecrypt )
729*cdf0e10cSrcweir         {
730*cdf0e10cSrcweir             EmitImplData* pEData = getEmitData( rContext );
731*cdf0e10cSrcweir             pEData->decrypt( reinterpret_cast<const sal_uInt8*>(*ppStream),
732*cdf0e10cSrcweir                              *pBytes,
733*cdf0e10cSrcweir                              reinterpret_cast<sal_uInt8*>(*ppStream),
734*cdf0e10cSrcweir                              m_nNumber,
735*cdf0e10cSrcweir                              m_nGeneration
736*cdf0e10cSrcweir                              ); // decrypt inplace
737*cdf0e10cSrcweir         }
738*cdf0e10cSrcweir     }
739*cdf0e10cSrcweir     else
740*cdf0e10cSrcweir         *ppStream = NULL, *pBytes = 0;
741*cdf0e10cSrcweir     return bIsDeflated;
742*cdf0e10cSrcweir }
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir static void unzipToBuffer( const char* pBegin, unsigned int nLen,
745*cdf0e10cSrcweir                            sal_uInt8** pOutBuf, sal_uInt32* pOutLen )
746*cdf0e10cSrcweir {
747*cdf0e10cSrcweir     z_stream aZStr;
748*cdf0e10cSrcweir     aZStr.next_in       = (Bytef*)pBegin;
749*cdf0e10cSrcweir     aZStr.avail_in      = nLen;
750*cdf0e10cSrcweir 	aZStr.zalloc        = ( alloc_func )0;
751*cdf0e10cSrcweir     aZStr.zfree         = ( free_func )0;
752*cdf0e10cSrcweir     aZStr.opaque        = ( voidpf )0;
753*cdf0e10cSrcweir     inflateInit(&aZStr);
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir     const unsigned int buf_increment_size = 16384;
756*cdf0e10cSrcweir 
757*cdf0e10cSrcweir     *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, buf_increment_size );
758*cdf0e10cSrcweir     aZStr.next_out      = (Bytef*)*pOutBuf;
759*cdf0e10cSrcweir     aZStr.avail_out     = buf_increment_size;
760*cdf0e10cSrcweir     int err = Z_OK;
761*cdf0e10cSrcweir     *pOutLen = buf_increment_size;
762*cdf0e10cSrcweir     while( err != Z_STREAM_END && err >= Z_OK && aZStr.avail_in )
763*cdf0e10cSrcweir     {
764*cdf0e10cSrcweir         err = inflate( &aZStr, Z_NO_FLUSH );
765*cdf0e10cSrcweir         if( aZStr.avail_out == 0 )
766*cdf0e10cSrcweir         {
767*cdf0e10cSrcweir             if( err != Z_STREAM_END )
768*cdf0e10cSrcweir             {
769*cdf0e10cSrcweir                 const int nNewAlloc = *pOutLen + buf_increment_size;
770*cdf0e10cSrcweir                 *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, nNewAlloc );
771*cdf0e10cSrcweir                 aZStr.next_out = (Bytef*)(*pOutBuf + *pOutLen);
772*cdf0e10cSrcweir                 aZStr.avail_out = buf_increment_size;
773*cdf0e10cSrcweir                 *pOutLen = nNewAlloc;
774*cdf0e10cSrcweir             }
775*cdf0e10cSrcweir         }
776*cdf0e10cSrcweir     }
777*cdf0e10cSrcweir     if( err == Z_STREAM_END )
778*cdf0e10cSrcweir     {
779*cdf0e10cSrcweir         if( aZStr.avail_out > 0 )
780*cdf0e10cSrcweir             *pOutLen -= aZStr.avail_out;;
781*cdf0e10cSrcweir     }
782*cdf0e10cSrcweir     inflateEnd(&aZStr);
783*cdf0e10cSrcweir     if( err < Z_OK )
784*cdf0e10cSrcweir     {
785*cdf0e10cSrcweir         rtl_freeMemory( *pOutBuf );
786*cdf0e10cSrcweir         *pOutBuf = NULL;
787*cdf0e10cSrcweir         *pOutLen = 0;
788*cdf0e10cSrcweir     }
789*cdf0e10cSrcweir }
790*cdf0e10cSrcweir 
791*cdf0e10cSrcweir bool PDFObject::writeStream( EmitContext& rWriteContext, const PDFFile* pParsedFile ) const
792*cdf0e10cSrcweir {
793*cdf0e10cSrcweir     bool bSuccess = false;
794*cdf0e10cSrcweir     if( m_pStream )
795*cdf0e10cSrcweir     {
796*cdf0e10cSrcweir         char* pStream = NULL;
797*cdf0e10cSrcweir         unsigned int nBytes = 0;
798*cdf0e10cSrcweir         if( getDeflatedStream( &pStream, &nBytes, pParsedFile, rWriteContext ) && nBytes && rWriteContext.m_bDeflate )
799*cdf0e10cSrcweir         {
800*cdf0e10cSrcweir             sal_uInt8* pOutBytes = NULL;
801*cdf0e10cSrcweir             sal_uInt32 nOutBytes = 0;
802*cdf0e10cSrcweir             unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
803*cdf0e10cSrcweir             rWriteContext.write( pOutBytes, nOutBytes );
804*cdf0e10cSrcweir             rtl_freeMemory( pOutBytes );
805*cdf0e10cSrcweir         }
806*cdf0e10cSrcweir         else if( pStream && nBytes )
807*cdf0e10cSrcweir             rWriteContext.write( pStream, nBytes );
808*cdf0e10cSrcweir         rtl_freeMemory( pStream );
809*cdf0e10cSrcweir     }
810*cdf0e10cSrcweir     return bSuccess;
811*cdf0e10cSrcweir }
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir bool PDFObject::emit( EmitContext& rWriteContext ) const
814*cdf0e10cSrcweir {
815*cdf0e10cSrcweir     if( ! rWriteContext.write( "\n", 1 ) )
816*cdf0e10cSrcweir         return false;
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir     EmitImplData* pEData = getEmitData( rWriteContext );
819*cdf0e10cSrcweir     if( pEData )
820*cdf0e10cSrcweir         pEData->insertXref( m_nNumber, m_nGeneration, rWriteContext.getCurPos() );
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir     OStringBuffer aBuf( 32 );
823*cdf0e10cSrcweir     aBuf.append( sal_Int32( m_nNumber ) );
824*cdf0e10cSrcweir     aBuf.append( ' ' );
825*cdf0e10cSrcweir     aBuf.append( sal_Int32( m_nGeneration ) );
826*cdf0e10cSrcweir     aBuf.append( " obj\n" );
827*cdf0e10cSrcweir     if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
828*cdf0e10cSrcweir         return false;
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir     if( pEData )
831*cdf0e10cSrcweir         pEData->setDecryptObject( m_nNumber, m_nGeneration );
832*cdf0e10cSrcweir     if( (rWriteContext.m_bDeflate || rWriteContext.m_bDecrypt) && pEData )
833*cdf0e10cSrcweir     {
834*cdf0e10cSrcweir         char* pStream = NULL;
835*cdf0e10cSrcweir         unsigned int nBytes = 0;
836*cdf0e10cSrcweir         bool bDeflate = getDeflatedStream( &pStream, &nBytes, pEData->m_pObjectContainer, rWriteContext );
837*cdf0e10cSrcweir         if( pStream && nBytes )
838*cdf0e10cSrcweir         {
839*cdf0e10cSrcweir             // unzip the stream
840*cdf0e10cSrcweir             sal_uInt8* pOutBytes = NULL;
841*cdf0e10cSrcweir             sal_uInt32 nOutBytes = 0;
842*cdf0e10cSrcweir             if( bDeflate && rWriteContext.m_bDeflate )
843*cdf0e10cSrcweir                 unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
844*cdf0e10cSrcweir             else
845*cdf0e10cSrcweir             {
846*cdf0e10cSrcweir                 // nothing to deflate, but decryption has happened
847*cdf0e10cSrcweir                 pOutBytes = (sal_uInt8*)pStream;
848*cdf0e10cSrcweir                 nOutBytes = (sal_uInt32)nBytes;
849*cdf0e10cSrcweir             }
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir             if( nOutBytes )
852*cdf0e10cSrcweir             {
853*cdf0e10cSrcweir                 // clone this object
854*cdf0e10cSrcweir                 PDFObject* pClone = static_cast<PDFObject*>(clone());
855*cdf0e10cSrcweir                 // set length in the dictionary to new stream length
856*cdf0e10cSrcweir                 PDFNumber* pNewLen = new PDFNumber( double(nOutBytes) );
857*cdf0e10cSrcweir                 pClone->m_pStream->m_pDict->insertValue( "Length", pNewLen );
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir                 if( bDeflate && rWriteContext.m_bDeflate )
860*cdf0e10cSrcweir                 {
861*cdf0e10cSrcweir                     // delete flatedecode filter
862*cdf0e10cSrcweir                     std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
863*cdf0e10cSrcweir                     pClone->m_pStream->m_pDict->m_aMap.find( "Filter" );
864*cdf0e10cSrcweir                     if( it != pClone->m_pStream->m_pDict->m_aMap.end() )
865*cdf0e10cSrcweir                     {
866*cdf0e10cSrcweir                         PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
867*cdf0e10cSrcweir                         if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
868*cdf0e10cSrcweir                             pClone->m_pStream->m_pDict->eraseValue( "Filter" );
869*cdf0e10cSrcweir                         else
870*cdf0e10cSrcweir                         {
871*cdf0e10cSrcweir                             PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
872*cdf0e10cSrcweir                             if( pArray && ! pArray->m_aSubElements.empty() )
873*cdf0e10cSrcweir                             {
874*cdf0e10cSrcweir                                 pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
875*cdf0e10cSrcweir                                 if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
876*cdf0e10cSrcweir                                 {
877*cdf0e10cSrcweir                                     delete pFilter;
878*cdf0e10cSrcweir                                     pArray->m_aSubElements.erase( pArray->m_aSubElements.begin() );
879*cdf0e10cSrcweir                                 }
880*cdf0e10cSrcweir                             }
881*cdf0e10cSrcweir                         }
882*cdf0e10cSrcweir                     }
883*cdf0e10cSrcweir                 }
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir                 // write sub elements except stream
886*cdf0e10cSrcweir                 bool bRet = true;
887*cdf0e10cSrcweir                 unsigned int nEle = pClone->m_aSubElements.size();
888*cdf0e10cSrcweir                 for( unsigned int i = 0; i < nEle && bRet; i++ )
889*cdf0e10cSrcweir                 {
890*cdf0e10cSrcweir                     if( pClone->m_aSubElements[i] != pClone->m_pStream )
891*cdf0e10cSrcweir                         bRet = pClone->m_aSubElements[i]->emit( rWriteContext );
892*cdf0e10cSrcweir                 }
893*cdf0e10cSrcweir                 delete pClone;
894*cdf0e10cSrcweir                 // write stream
895*cdf0e10cSrcweir                 if( bRet )
896*cdf0e10cSrcweir                     rWriteContext.write( "stream\n", 7 );
897*cdf0e10cSrcweir                 if( bRet )
898*cdf0e10cSrcweir                     bRet = rWriteContext.write( pOutBytes, nOutBytes );
899*cdf0e10cSrcweir                 if( bRet )
900*cdf0e10cSrcweir                     bRet = rWriteContext.write( "\nendstream\nendobj\n", 18 );
901*cdf0e10cSrcweir                 rtl_freeMemory( pStream );
902*cdf0e10cSrcweir                 if( pOutBytes != (sal_uInt8*)pStream )
903*cdf0e10cSrcweir                     rtl_freeMemory( pOutBytes );
904*cdf0e10cSrcweir                 if( pEData )
905*cdf0e10cSrcweir                     pEData->setDecryptObject( 0, 0 );
906*cdf0e10cSrcweir                 return bRet;
907*cdf0e10cSrcweir             }
908*cdf0e10cSrcweir             if( pOutBytes != (sal_uInt8*)pStream )
909*cdf0e10cSrcweir                 rtl_freeMemory( pOutBytes );
910*cdf0e10cSrcweir         }
911*cdf0e10cSrcweir         rtl_freeMemory( pStream );
912*cdf0e10cSrcweir     }
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir     bool bRet = emitSubElements( rWriteContext ) &&
915*cdf0e10cSrcweir                 rWriteContext.write( "\nendobj\n", 8 );
916*cdf0e10cSrcweir     if( pEData )
917*cdf0e10cSrcweir         pEData->setDecryptObject( 0, 0 );
918*cdf0e10cSrcweir     return bRet;
919*cdf0e10cSrcweir }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir PDFEntry* PDFObject::clone() const
922*cdf0e10cSrcweir {
923*cdf0e10cSrcweir     PDFObject* pNewOb = new PDFObject( m_nNumber, m_nGeneration );
924*cdf0e10cSrcweir     cloneSubElements( pNewOb->m_aSubElements );
925*cdf0e10cSrcweir     unsigned int nEle = m_aSubElements.size();
926*cdf0e10cSrcweir     for( unsigned int i = 0; i < nEle; i++ )
927*cdf0e10cSrcweir     {
928*cdf0e10cSrcweir         if( m_aSubElements[i] == m_pObject )
929*cdf0e10cSrcweir             pNewOb->m_pObject = pNewOb->m_aSubElements[i];
930*cdf0e10cSrcweir         else if( m_aSubElements[i] == m_pStream && pNewOb->m_pObject )
931*cdf0e10cSrcweir         {
932*cdf0e10cSrcweir             pNewOb->m_pStream = dynamic_cast<PDFStream*>(pNewOb->m_aSubElements[i]);
933*cdf0e10cSrcweir             PDFDict* pNewDict = dynamic_cast<PDFDict*>(pNewOb->m_pObject);
934*cdf0e10cSrcweir             if( pNewDict )
935*cdf0e10cSrcweir                 pNewOb->m_pStream->m_pDict = pNewDict;
936*cdf0e10cSrcweir         }
937*cdf0e10cSrcweir     }
938*cdf0e10cSrcweir     return pNewOb;
939*cdf0e10cSrcweir }
940*cdf0e10cSrcweir 
941*cdf0e10cSrcweir PDFTrailer::~PDFTrailer()
942*cdf0e10cSrcweir {
943*cdf0e10cSrcweir }
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir bool PDFTrailer::emit( EmitContext& rWriteContext ) const
946*cdf0e10cSrcweir {
947*cdf0e10cSrcweir     // get xref offset
948*cdf0e10cSrcweir     unsigned int nXRefPos = rWriteContext.getCurPos();
949*cdf0e10cSrcweir     // begin xref section, object 0 is always free
950*cdf0e10cSrcweir     if( ! rWriteContext.write( "xref\r\n"
951*cdf0e10cSrcweir                                "0 1\r\n"
952*cdf0e10cSrcweir                                "0000000000 65535 f\r\n", 31 ) )
953*cdf0e10cSrcweir         return false;
954*cdf0e10cSrcweir     // check if we are emitting a complete PDF file
955*cdf0e10cSrcweir     EmitImplData* pEData = getEmitData( rWriteContext );
956*cdf0e10cSrcweir     if( pEData )
957*cdf0e10cSrcweir     {
958*cdf0e10cSrcweir         // emit object xrefs
959*cdf0e10cSrcweir         const EmitImplData::XRefTable& rXRefs = pEData->m_aXRefTable;
960*cdf0e10cSrcweir         EmitImplData::XRefTable::const_iterator section_begin, section_end;
961*cdf0e10cSrcweir         section_begin = rXRefs.begin();
962*cdf0e10cSrcweir         while( section_begin != rXRefs.end() )
963*cdf0e10cSrcweir         {
964*cdf0e10cSrcweir             // find end of continuous object numbers
965*cdf0e10cSrcweir             section_end = section_begin;
966*cdf0e10cSrcweir             unsigned int nLast = section_begin->first;
967*cdf0e10cSrcweir             while( (++section_end) != rXRefs.end() &&
968*cdf0e10cSrcweir                    section_end->first == nLast+1 )
969*cdf0e10cSrcweir                 nLast = section_end->first;
970*cdf0e10cSrcweir             // write first object number and number of following entries
971*cdf0e10cSrcweir             OStringBuffer aBuf( 21 );
972*cdf0e10cSrcweir             aBuf.append( sal_Int32( section_begin->first ) );
973*cdf0e10cSrcweir             aBuf.append( ' ' );
974*cdf0e10cSrcweir             aBuf.append( sal_Int32(nLast - section_begin->first + 1) );
975*cdf0e10cSrcweir             aBuf.append( "\r\n" );
976*cdf0e10cSrcweir             if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
977*cdf0e10cSrcweir                 return false;
978*cdf0e10cSrcweir             while( section_begin != section_end )
979*cdf0e10cSrcweir             {
980*cdf0e10cSrcweir                 // write 20 char entry of form
981*cdf0e10cSrcweir                 // 0000offset 00gen n\r\n
982*cdf0e10cSrcweir                 aBuf.setLength( 0 );
983*cdf0e10cSrcweir                 OString aOffset( OString::valueOf( sal_Int64(section_begin->second.second ) ) );
984*cdf0e10cSrcweir                 int nPad = 10 - aOffset.getLength();
985*cdf0e10cSrcweir                 for( int i = 0; i < nPad; i++ )
986*cdf0e10cSrcweir                     aBuf.append( '0' );
987*cdf0e10cSrcweir                 aBuf.append( aOffset );
988*cdf0e10cSrcweir                 aBuf.append( ' ' );
989*cdf0e10cSrcweir                 OString aGeneration( OString::valueOf( sal_Int32(section_begin->second.first ) ) );
990*cdf0e10cSrcweir                 nPad = 5 - aGeneration.getLength();
991*cdf0e10cSrcweir                 for( int i = 0; i < nPad; i++ )
992*cdf0e10cSrcweir                     aBuf.append( '0' );
993*cdf0e10cSrcweir                 aBuf.append( aGeneration );
994*cdf0e10cSrcweir                 aBuf.append( " n\r\n" );
995*cdf0e10cSrcweir                 if( ! rWriteContext.write( aBuf.getStr(), 20 ) )
996*cdf0e10cSrcweir                     return false;
997*cdf0e10cSrcweir                 ++section_begin;
998*cdf0e10cSrcweir             }
999*cdf0e10cSrcweir         }
1000*cdf0e10cSrcweir     }
1001*cdf0e10cSrcweir     if( ! rWriteContext.write( "trailer\n", 8 ) )
1002*cdf0e10cSrcweir         return false;
1003*cdf0e10cSrcweir     if( ! emitSubElements( rWriteContext ) )
1004*cdf0e10cSrcweir         return false;
1005*cdf0e10cSrcweir     if( ! rWriteContext.write( "startxref\n", 10 ) )
1006*cdf0e10cSrcweir         return false;
1007*cdf0e10cSrcweir     rtl::OString aOffset( rtl::OString::valueOf( sal_Int32(nXRefPos) ) );
1008*cdf0e10cSrcweir     if( ! rWriteContext.write( aOffset.getStr(), aOffset.getLength() ) )
1009*cdf0e10cSrcweir         return false;
1010*cdf0e10cSrcweir     return rWriteContext.write( "\n%%EOF\n", 7 );
1011*cdf0e10cSrcweir }
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir PDFEntry* PDFTrailer::clone() const
1014*cdf0e10cSrcweir {
1015*cdf0e10cSrcweir     PDFTrailer* pNewTr = new PDFTrailer();
1016*cdf0e10cSrcweir     cloneSubElements( pNewTr->m_aSubElements );
1017*cdf0e10cSrcweir     unsigned int nEle = m_aSubElements.size();
1018*cdf0e10cSrcweir     for( unsigned int i = 0; i < nEle; i++ )
1019*cdf0e10cSrcweir     {
1020*cdf0e10cSrcweir         if( m_aSubElements[i] == m_pDict )
1021*cdf0e10cSrcweir         {
1022*cdf0e10cSrcweir             pNewTr->m_pDict = dynamic_cast<PDFDict*>(pNewTr->m_aSubElements[i]);
1023*cdf0e10cSrcweir             break;
1024*cdf0e10cSrcweir         }
1025*cdf0e10cSrcweir     }
1026*cdf0e10cSrcweir     return pNewTr;
1027*cdf0e10cSrcweir }
1028*cdf0e10cSrcweir 
1029*cdf0e10cSrcweir #define ENCRYPTION_KEY_LEN 16
1030*cdf0e10cSrcweir #define ENCRYPTION_BUF_LEN 32
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir namespace pdfparse {
1033*cdf0e10cSrcweir struct PDFFileImplData
1034*cdf0e10cSrcweir {
1035*cdf0e10cSrcweir     bool        m_bIsEncrypted;
1036*cdf0e10cSrcweir     bool        m_bStandardHandler;
1037*cdf0e10cSrcweir     sal_uInt32  m_nAlgoVersion;
1038*cdf0e10cSrcweir     sal_uInt32  m_nStandardRevision;
1039*cdf0e10cSrcweir     sal_uInt32  m_nKeyLength;
1040*cdf0e10cSrcweir     sal_uInt8   m_aOEntry[32];
1041*cdf0e10cSrcweir     sal_uInt8   m_aUEntry[32];
1042*cdf0e10cSrcweir     sal_uInt32  m_nPEntry;
1043*cdf0e10cSrcweir     OString     m_aDocID;
1044*cdf0e10cSrcweir     rtlCipher   m_aCipher;
1045*cdf0e10cSrcweir     rtlDigest   m_aDigest;
1046*cdf0e10cSrcweir 
1047*cdf0e10cSrcweir     sal_uInt8   m_aDecryptionKey[ENCRYPTION_KEY_LEN+5]; // maximum handled key length
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir     PDFFileImplData() :
1050*cdf0e10cSrcweir         m_bIsEncrypted( false ),
1051*cdf0e10cSrcweir         m_bStandardHandler( false ),
1052*cdf0e10cSrcweir         m_nAlgoVersion( 0 ),
1053*cdf0e10cSrcweir         m_nStandardRevision( 0 ),
1054*cdf0e10cSrcweir         m_nKeyLength( 0 ),
1055*cdf0e10cSrcweir         m_nPEntry( 0 ),
1056*cdf0e10cSrcweir         m_aCipher( NULL ),
1057*cdf0e10cSrcweir         m_aDigest( NULL )
1058*cdf0e10cSrcweir     {
1059*cdf0e10cSrcweir         rtl_zeroMemory( m_aOEntry, sizeof( m_aOEntry ) );
1060*cdf0e10cSrcweir         rtl_zeroMemory( m_aUEntry, sizeof( m_aUEntry ) );
1061*cdf0e10cSrcweir         rtl_zeroMemory( m_aDecryptionKey, sizeof( m_aDecryptionKey ) );
1062*cdf0e10cSrcweir     }
1063*cdf0e10cSrcweir 
1064*cdf0e10cSrcweir     ~PDFFileImplData()
1065*cdf0e10cSrcweir     {
1066*cdf0e10cSrcweir         if( m_aCipher )
1067*cdf0e10cSrcweir             rtl_cipher_destroyARCFOUR( m_aCipher );
1068*cdf0e10cSrcweir         if( m_aDigest )
1069*cdf0e10cSrcweir             rtl_digest_destroyMD5( m_aDigest );
1070*cdf0e10cSrcweir     }
1071*cdf0e10cSrcweir };
1072*cdf0e10cSrcweir }
1073*cdf0e10cSrcweir 
1074*cdf0e10cSrcweir PDFFile::~PDFFile()
1075*cdf0e10cSrcweir {
1076*cdf0e10cSrcweir     if( m_pData )
1077*cdf0e10cSrcweir         delete m_pData;
1078*cdf0e10cSrcweir }
1079*cdf0e10cSrcweir 
1080*cdf0e10cSrcweir bool PDFFile::isEncrypted() const
1081*cdf0e10cSrcweir {
1082*cdf0e10cSrcweir     return impl_getData()->m_bIsEncrypted;
1083*cdf0e10cSrcweir }
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir bool PDFFile::decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
1086*cdf0e10cSrcweir                        unsigned int nObject, unsigned int nGeneration ) const
1087*cdf0e10cSrcweir {
1088*cdf0e10cSrcweir     if( ! isEncrypted() )
1089*cdf0e10cSrcweir         return false;
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir     if( ! m_pData->m_aCipher )
1092*cdf0e10cSrcweir         m_pData->m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream );
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir     // modify encryption key
1095*cdf0e10cSrcweir     sal_uInt32 i = m_pData->m_nKeyLength;
1096*cdf0e10cSrcweir     m_pData->m_aDecryptionKey[i++] = sal_uInt8(nObject&0xff);
1097*cdf0e10cSrcweir     m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>8)&0xff);
1098*cdf0e10cSrcweir     m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>16)&0xff);
1099*cdf0e10cSrcweir     m_pData->m_aDecryptionKey[i++] = sal_uInt8(nGeneration&0xff);
1100*cdf0e10cSrcweir     m_pData->m_aDecryptionKey[i++] = sal_uInt8((nGeneration>>8)&0xff);
1101*cdf0e10cSrcweir 
1102*cdf0e10cSrcweir     sal_uInt8 aSum[ENCRYPTION_KEY_LEN];
1103*cdf0e10cSrcweir     rtl_digest_updateMD5( m_pData->m_aDigest, m_pData->m_aDecryptionKey, i );
1104*cdf0e10cSrcweir     rtl_digest_getMD5( m_pData->m_aDigest, aSum, sizeof( aSum ) );
1105*cdf0e10cSrcweir 
1106*cdf0e10cSrcweir     if( i > 16 )
1107*cdf0e10cSrcweir         i = 16;
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir     rtlCipherError aErr = rtl_cipher_initARCFOUR( m_pData->m_aCipher,
1110*cdf0e10cSrcweir                                                   rtl_Cipher_DirectionDecode,
1111*cdf0e10cSrcweir                                                   aSum, i,
1112*cdf0e10cSrcweir                                                   NULL, 0 );
1113*cdf0e10cSrcweir     if( aErr == rtl_Cipher_E_None )
1114*cdf0e10cSrcweir         aErr = rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
1115*cdf0e10cSrcweir                                          pInBuffer, nLen,
1116*cdf0e10cSrcweir                                          pOutBuffer, nLen );
1117*cdf0e10cSrcweir     return aErr == rtl_Cipher_E_None;
1118*cdf0e10cSrcweir }
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir static const sal_uInt8 nPadString[32] =
1121*cdf0e10cSrcweir {
1122*cdf0e10cSrcweir     0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
1123*cdf0e10cSrcweir     0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
1124*cdf0e10cSrcweir };
1125*cdf0e10cSrcweir 
1126*cdf0e10cSrcweir static void pad_or_truncate_to_32( const OString& rStr, sal_Char* pBuffer )
1127*cdf0e10cSrcweir {
1128*cdf0e10cSrcweir     int nLen = rStr.getLength();
1129*cdf0e10cSrcweir     if( nLen > 32 )
1130*cdf0e10cSrcweir         nLen = 32;
1131*cdf0e10cSrcweir     const sal_Char* pStr = rStr.getStr();
1132*cdf0e10cSrcweir     rtl_copyMemory( pBuffer, pStr, nLen );
1133*cdf0e10cSrcweir     int i = 0;
1134*cdf0e10cSrcweir     while( nLen < 32 )
1135*cdf0e10cSrcweir         pBuffer[nLen++] = nPadString[i++];
1136*cdf0e10cSrcweir }
1137*cdf0e10cSrcweir 
1138*cdf0e10cSrcweir // pass at least pData->m_nKeyLength bytes in
1139*cdf0e10cSrcweir static sal_uInt32 password_to_key( const OString& rPwd, sal_uInt8* pOutKey, PDFFileImplData* pData, bool bComputeO )
1140*cdf0e10cSrcweir {
1141*cdf0e10cSrcweir     // see PDF reference 1.4 Algorithm 3.2
1142*cdf0e10cSrcweir     // encrypt pad string
1143*cdf0e10cSrcweir     sal_Char aPadPwd[ENCRYPTION_BUF_LEN];
1144*cdf0e10cSrcweir     pad_or_truncate_to_32( rPwd, aPadPwd );
1145*cdf0e10cSrcweir     rtl_digest_updateMD5( pData->m_aDigest, aPadPwd, sizeof( aPadPwd ) );
1146*cdf0e10cSrcweir     if( ! bComputeO )
1147*cdf0e10cSrcweir     {
1148*cdf0e10cSrcweir         rtl_digest_updateMD5( pData->m_aDigest, pData->m_aOEntry, 32 );
1149*cdf0e10cSrcweir         sal_uInt8 aPEntry[4];
1150*cdf0e10cSrcweir         aPEntry[0] = static_cast<sal_uInt8>(pData->m_nPEntry & 0xff);
1151*cdf0e10cSrcweir         aPEntry[1] = static_cast<sal_uInt8>((pData->m_nPEntry >> 8 ) & 0xff);
1152*cdf0e10cSrcweir         aPEntry[2] = static_cast<sal_uInt8>((pData->m_nPEntry >> 16) & 0xff);
1153*cdf0e10cSrcweir         aPEntry[3] = static_cast<sal_uInt8>((pData->m_nPEntry >> 24) & 0xff);
1154*cdf0e10cSrcweir         rtl_digest_updateMD5( pData->m_aDigest, aPEntry, sizeof(aPEntry) );
1155*cdf0e10cSrcweir         rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
1156*cdf0e10cSrcweir     }
1157*cdf0e10cSrcweir     sal_uInt8 nSum[RTL_DIGEST_LENGTH_MD5];
1158*cdf0e10cSrcweir     rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) );
1159*cdf0e10cSrcweir     if( pData->m_nStandardRevision == 3 )
1160*cdf0e10cSrcweir     {
1161*cdf0e10cSrcweir         for( int i = 0; i < 50; i++ )
1162*cdf0e10cSrcweir         {
1163*cdf0e10cSrcweir             rtl_digest_updateMD5( pData->m_aDigest, nSum, sizeof(nSum) );
1164*cdf0e10cSrcweir             rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) );
1165*cdf0e10cSrcweir         }
1166*cdf0e10cSrcweir     }
1167*cdf0e10cSrcweir     sal_uInt32 nLen = pData->m_nKeyLength;
1168*cdf0e10cSrcweir     if( nLen > RTL_DIGEST_LENGTH_MD5 )
1169*cdf0e10cSrcweir         nLen = RTL_DIGEST_LENGTH_MD5;
1170*cdf0e10cSrcweir     rtl_copyMemory( pOutKey, nSum, nLen );
1171*cdf0e10cSrcweir     return nLen;
1172*cdf0e10cSrcweir }
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir static bool check_user_password( const OString& rPwd, PDFFileImplData* pData )
1175*cdf0e10cSrcweir {
1176*cdf0e10cSrcweir     // see PDF reference 1.4 Algorithm 3.6
1177*cdf0e10cSrcweir     bool bValid = false;
1178*cdf0e10cSrcweir     sal_uInt8 aKey[ENCRYPTION_KEY_LEN];
1179*cdf0e10cSrcweir     sal_uInt8 nEncryptedEntry[ENCRYPTION_BUF_LEN];
1180*cdf0e10cSrcweir     rtl_zeroMemory( nEncryptedEntry, sizeof(nEncryptedEntry) );
1181*cdf0e10cSrcweir     sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, pData, false );
1182*cdf0e10cSrcweir     // save (at this time potential) decryption key for later use
1183*cdf0e10cSrcweir     rtl_copyMemory( pData->m_aDecryptionKey, aKey, nKeyLen );
1184*cdf0e10cSrcweir     if( pData->m_nStandardRevision == 2 )
1185*cdf0e10cSrcweir     {
1186*cdf0e10cSrcweir         // see PDF reference 1.4 Algorithm 3.4
1187*cdf0e10cSrcweir         // encrypt pad string
1188*cdf0e10cSrcweir         rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
1189*cdf0e10cSrcweir                                 aKey, nKeyLen,
1190*cdf0e10cSrcweir                                 NULL, 0 );
1191*cdf0e10cSrcweir         rtl_cipher_encodeARCFOUR( pData->m_aCipher, nPadString, sizeof( nPadString ),
1192*cdf0e10cSrcweir                                   nEncryptedEntry, sizeof( nEncryptedEntry ) );
1193*cdf0e10cSrcweir         bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 32 ) == 0);
1194*cdf0e10cSrcweir     }
1195*cdf0e10cSrcweir     else if( pData->m_nStandardRevision == 3 )
1196*cdf0e10cSrcweir     {
1197*cdf0e10cSrcweir         // see PDF reference 1.4 Algorithm 3.5
1198*cdf0e10cSrcweir         rtl_digest_updateMD5( pData->m_aDigest, nPadString, sizeof( nPadString ) );
1199*cdf0e10cSrcweir         rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
1200*cdf0e10cSrcweir         rtl_digest_getMD5( pData->m_aDigest, nEncryptedEntry, sizeof(nEncryptedEntry) );
1201*cdf0e10cSrcweir         rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
1202*cdf0e10cSrcweir                                 aKey, sizeof(aKey), NULL, 0 );
1203*cdf0e10cSrcweir         rtl_cipher_encodeARCFOUR( pData->m_aCipher,
1204*cdf0e10cSrcweir                                   nEncryptedEntry, 16,
1205*cdf0e10cSrcweir                                   nEncryptedEntry, 16 ); // encrypt in place
1206*cdf0e10cSrcweir         for( int i = 1; i <= 19; i++ ) // do it 19 times, start with 1
1207*cdf0e10cSrcweir         {
1208*cdf0e10cSrcweir             sal_uInt8 aTempKey[ENCRYPTION_KEY_LEN];
1209*cdf0e10cSrcweir             for( sal_uInt32 j = 0; j < sizeof(aTempKey); j++ )
1210*cdf0e10cSrcweir                 aTempKey[j] = static_cast<sal_uInt8>( aKey[j] ^ i );
1211*cdf0e10cSrcweir 
1212*cdf0e10cSrcweir             rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
1213*cdf0e10cSrcweir                                     aTempKey, sizeof(aTempKey), NULL, 0 );
1214*cdf0e10cSrcweir             rtl_cipher_encodeARCFOUR( pData->m_aCipher,
1215*cdf0e10cSrcweir                                       nEncryptedEntry, 16,
1216*cdf0e10cSrcweir                                       nEncryptedEntry, 16 ); // encrypt in place
1217*cdf0e10cSrcweir         }
1218*cdf0e10cSrcweir         bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 16 ) == 0);
1219*cdf0e10cSrcweir     }
1220*cdf0e10cSrcweir     return bValid;
1221*cdf0e10cSrcweir }
1222*cdf0e10cSrcweir 
1223*cdf0e10cSrcweir bool PDFFile::setupDecryptionData( const OString& rPwd ) const
1224*cdf0e10cSrcweir {
1225*cdf0e10cSrcweir     if( !impl_getData()->m_bIsEncrypted )
1226*cdf0e10cSrcweir         return rPwd.getLength() == 0;
1227*cdf0e10cSrcweir 
1228*cdf0e10cSrcweir     // check if we can handle this encryption at all
1229*cdf0e10cSrcweir     if( ! m_pData->m_bStandardHandler ||
1230*cdf0e10cSrcweir         m_pData->m_nAlgoVersion < 1 ||
1231*cdf0e10cSrcweir         m_pData->m_nAlgoVersion > 2 ||
1232*cdf0e10cSrcweir         m_pData->m_nStandardRevision < 2 ||
1233*cdf0e10cSrcweir         m_pData->m_nStandardRevision > 3 )
1234*cdf0e10cSrcweir         return false;
1235*cdf0e10cSrcweir 
1236*cdf0e10cSrcweir     if( ! m_pData->m_aCipher )
1237*cdf0e10cSrcweir         m_pData->m_aCipher = rtl_cipher_createARCFOUR(rtl_Cipher_ModeStream);
1238*cdf0e10cSrcweir     if( ! m_pData->m_aDigest )
1239*cdf0e10cSrcweir         m_pData->m_aDigest = rtl_digest_createMD5();
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir     // first try user password
1242*cdf0e10cSrcweir     bool bValid = check_user_password( rPwd, m_pData );
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir     if( ! bValid )
1245*cdf0e10cSrcweir     {
1246*cdf0e10cSrcweir         // try owner password
1247*cdf0e10cSrcweir         // see PDF reference 1.4 Algorithm 3.7
1248*cdf0e10cSrcweir         sal_uInt8 aKey[ENCRYPTION_KEY_LEN];
1249*cdf0e10cSrcweir         sal_uInt8 nPwd[ENCRYPTION_BUF_LEN];
1250*cdf0e10cSrcweir         rtl_zeroMemory( nPwd, sizeof(nPwd) );
1251*cdf0e10cSrcweir         sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, m_pData, true );
1252*cdf0e10cSrcweir         if( m_pData->m_nStandardRevision == 2 )
1253*cdf0e10cSrcweir         {
1254*cdf0e10cSrcweir             rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
1255*cdf0e10cSrcweir                                     aKey, nKeyLen, NULL, 0 );
1256*cdf0e10cSrcweir             rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
1257*cdf0e10cSrcweir                                       m_pData->m_aOEntry, 32,
1258*cdf0e10cSrcweir                                       nPwd, 32 );
1259*cdf0e10cSrcweir         }
1260*cdf0e10cSrcweir         else if( m_pData->m_nStandardRevision == 3 )
1261*cdf0e10cSrcweir         {
1262*cdf0e10cSrcweir             rtl_copyMemory( nPwd, m_pData->m_aOEntry, 32 );
1263*cdf0e10cSrcweir             for( int i = 19; i >= 0; i-- )
1264*cdf0e10cSrcweir             {
1265*cdf0e10cSrcweir                 sal_uInt8 nTempKey[ENCRYPTION_KEY_LEN];
1266*cdf0e10cSrcweir                 for( unsigned int j = 0; j < sizeof(nTempKey); j++ )
1267*cdf0e10cSrcweir                     nTempKey[j] = sal_uInt8(aKey[j] ^ i);
1268*cdf0e10cSrcweir                 rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
1269*cdf0e10cSrcweir                                         nTempKey, nKeyLen, NULL, 0 );
1270*cdf0e10cSrcweir                 rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
1271*cdf0e10cSrcweir                                           nPwd, 32,
1272*cdf0e10cSrcweir                                           nPwd, 32 ); // decrypt inplace
1273*cdf0e10cSrcweir             }
1274*cdf0e10cSrcweir         }
1275*cdf0e10cSrcweir         bValid = check_user_password( OString( (sal_Char*)nPwd, 32 ), m_pData );
1276*cdf0e10cSrcweir     }
1277*cdf0e10cSrcweir 
1278*cdf0e10cSrcweir     return bValid;
1279*cdf0e10cSrcweir }
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir rtl::OUString PDFFile::getDecryptionKey() const
1282*cdf0e10cSrcweir {
1283*cdf0e10cSrcweir     rtl::OUStringBuffer aBuf( ENCRYPTION_KEY_LEN * 2 );
1284*cdf0e10cSrcweir     if( impl_getData()->m_bIsEncrypted )
1285*cdf0e10cSrcweir     {
1286*cdf0e10cSrcweir         for( sal_uInt32 i = 0; i < m_pData->m_nKeyLength; i++ )
1287*cdf0e10cSrcweir         {
1288*cdf0e10cSrcweir             static const sal_Unicode pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
1289*cdf0e10cSrcweir                                                      '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1290*cdf0e10cSrcweir             aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] >> 4) & 0x0f] );
1291*cdf0e10cSrcweir             aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] & 0x0f)] );
1292*cdf0e10cSrcweir         }
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir     }
1295*cdf0e10cSrcweir     return aBuf.makeStringAndClear();
1296*cdf0e10cSrcweir }
1297*cdf0e10cSrcweir 
1298*cdf0e10cSrcweir PDFFileImplData* PDFFile::impl_getData() const
1299*cdf0e10cSrcweir {
1300*cdf0e10cSrcweir     if( m_pData )
1301*cdf0e10cSrcweir         return m_pData;
1302*cdf0e10cSrcweir     m_pData = new PDFFileImplData();
1303*cdf0e10cSrcweir     // check for encryption dict in a trailer
1304*cdf0e10cSrcweir     unsigned int nElements = m_aSubElements.size();
1305*cdf0e10cSrcweir     while( nElements-- > 0 )
1306*cdf0e10cSrcweir     {
1307*cdf0e10cSrcweir         PDFTrailer* pTrailer = dynamic_cast<PDFTrailer*>(m_aSubElements[nElements]);
1308*cdf0e10cSrcweir         if( pTrailer && pTrailer->m_pDict )
1309*cdf0e10cSrcweir         {
1310*cdf0e10cSrcweir             // search doc id
1311*cdf0e10cSrcweir             PDFDict::Map::iterator doc_id = pTrailer->m_pDict->m_aMap.find( "ID" );
1312*cdf0e10cSrcweir             if( doc_id != pTrailer->m_pDict->m_aMap.end() )
1313*cdf0e10cSrcweir             {
1314*cdf0e10cSrcweir                 PDFArray* pArr = dynamic_cast<PDFArray*>(doc_id->second);
1315*cdf0e10cSrcweir                 if( pArr && pArr->m_aSubElements.size() > 0 )
1316*cdf0e10cSrcweir                 {
1317*cdf0e10cSrcweir                     PDFString* pStr = dynamic_cast<PDFString*>(pArr->m_aSubElements[0]);
1318*cdf0e10cSrcweir                     if( pStr )
1319*cdf0e10cSrcweir                         m_pData->m_aDocID = pStr->getFilteredString();
1320*cdf0e10cSrcweir                     #if OSL_DEBUG_LEVEL > 1
1321*cdf0e10cSrcweir                     fprintf( stderr, "DocId is <" );
1322*cdf0e10cSrcweir                     for( int i = 0; i < m_pData->m_aDocID.getLength(); i++ )
1323*cdf0e10cSrcweir                         fprintf( stderr, "%.2x", (unsigned int)sal_uInt8(m_pData->m_aDocID.getStr()[i]) );
1324*cdf0e10cSrcweir                     fprintf( stderr, ">\n" );
1325*cdf0e10cSrcweir                     #endif
1326*cdf0e10cSrcweir                 }
1327*cdf0e10cSrcweir             }
1328*cdf0e10cSrcweir             // search Encrypt entry
1329*cdf0e10cSrcweir             PDFDict::Map::iterator enc =
1330*cdf0e10cSrcweir                 pTrailer->m_pDict->m_aMap.find( "Encrypt" );
1331*cdf0e10cSrcweir             if( enc != pTrailer->m_pDict->m_aMap.end() )
1332*cdf0e10cSrcweir             {
1333*cdf0e10cSrcweir                 PDFDict* pDict = dynamic_cast<PDFDict*>(enc->second);
1334*cdf0e10cSrcweir                 if( ! pDict )
1335*cdf0e10cSrcweir                 {
1336*cdf0e10cSrcweir                     PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(enc->second);
1337*cdf0e10cSrcweir                     if( pRef )
1338*cdf0e10cSrcweir                     {
1339*cdf0e10cSrcweir                         PDFObject* pObj = findObject( pRef );
1340*cdf0e10cSrcweir                         if( pObj && pObj->m_pObject )
1341*cdf0e10cSrcweir                             pDict = dynamic_cast<PDFDict*>(pObj->m_pObject);
1342*cdf0e10cSrcweir                     }
1343*cdf0e10cSrcweir                 }
1344*cdf0e10cSrcweir                 if( pDict )
1345*cdf0e10cSrcweir                 {
1346*cdf0e10cSrcweir                     PDFDict::Map::iterator filter = pDict->m_aMap.find( "Filter" );
1347*cdf0e10cSrcweir                     PDFDict::Map::iterator version = pDict->m_aMap.find( "V" );
1348*cdf0e10cSrcweir                     PDFDict::Map::iterator len = pDict->m_aMap.find( "Length" );
1349*cdf0e10cSrcweir                     PDFDict::Map::iterator o_ent = pDict->m_aMap.find( "O" );
1350*cdf0e10cSrcweir                     PDFDict::Map::iterator u_ent = pDict->m_aMap.find( "U" );
1351*cdf0e10cSrcweir                     PDFDict::Map::iterator r_ent = pDict->m_aMap.find( "R" );
1352*cdf0e10cSrcweir                     PDFDict::Map::iterator p_ent = pDict->m_aMap.find( "P" );
1353*cdf0e10cSrcweir                     if( filter != pDict->m_aMap.end() )
1354*cdf0e10cSrcweir                     {
1355*cdf0e10cSrcweir                         m_pData->m_bIsEncrypted = true;
1356*cdf0e10cSrcweir                         m_pData->m_nKeyLength = 5;
1357*cdf0e10cSrcweir                         if( version != pDict->m_aMap.end() )
1358*cdf0e10cSrcweir                         {
1359*cdf0e10cSrcweir                             PDFNumber* pNum = dynamic_cast<PDFNumber*>(version->second);
1360*cdf0e10cSrcweir                             if( pNum )
1361*cdf0e10cSrcweir                                 m_pData->m_nAlgoVersion = static_cast<sal_uInt32>(pNum->m_fValue);
1362*cdf0e10cSrcweir                         }
1363*cdf0e10cSrcweir                         if( m_pData->m_nAlgoVersion >= 3 )
1364*cdf0e10cSrcweir                             m_pData->m_nKeyLength = 16;
1365*cdf0e10cSrcweir                         if( len != pDict->m_aMap.end() )
1366*cdf0e10cSrcweir                         {
1367*cdf0e10cSrcweir                             PDFNumber* pNum = dynamic_cast<PDFNumber*>(len->second);
1368*cdf0e10cSrcweir                             if( pNum )
1369*cdf0e10cSrcweir                                 m_pData->m_nKeyLength = static_cast<sal_uInt32>(pNum->m_fValue) / 8;
1370*cdf0e10cSrcweir                         }
1371*cdf0e10cSrcweir                         PDFName* pFilter = dynamic_cast<PDFName*>(filter->second);
1372*cdf0e10cSrcweir                         if( pFilter && pFilter->getFilteredName().equalsAscii( "Standard" ) )
1373*cdf0e10cSrcweir                             m_pData->m_bStandardHandler = true;
1374*cdf0e10cSrcweir                         if( o_ent != pDict->m_aMap.end() )
1375*cdf0e10cSrcweir                         {
1376*cdf0e10cSrcweir                             PDFString* pString = dynamic_cast<PDFString*>(o_ent->second);
1377*cdf0e10cSrcweir                             if( pString )
1378*cdf0e10cSrcweir                             {
1379*cdf0e10cSrcweir                                 OString aEnt = pString->getFilteredString();
1380*cdf0e10cSrcweir                                 if( aEnt.getLength() == 32 )
1381*cdf0e10cSrcweir                                     rtl_copyMemory( m_pData->m_aOEntry, aEnt.getStr(), 32 );
1382*cdf0e10cSrcweir                                 #if OSL_DEBUG_LEVEL > 1
1383*cdf0e10cSrcweir                                 else
1384*cdf0e10cSrcweir                                 {
1385*cdf0e10cSrcweir                                     fprintf( stderr, "O entry has length %d, should be 32 <", (int)aEnt.getLength() );
1386*cdf0e10cSrcweir                                     for( int i = 0; i < aEnt.getLength(); i++ )
1387*cdf0e10cSrcweir                                         fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) );
1388*cdf0e10cSrcweir                                     fprintf( stderr, ">\n" );
1389*cdf0e10cSrcweir                                 }
1390*cdf0e10cSrcweir                                 #endif
1391*cdf0e10cSrcweir                             }
1392*cdf0e10cSrcweir                         }
1393*cdf0e10cSrcweir                         if( u_ent != pDict->m_aMap.end() )
1394*cdf0e10cSrcweir                         {
1395*cdf0e10cSrcweir                             PDFString* pString = dynamic_cast<PDFString*>(u_ent->second);
1396*cdf0e10cSrcweir                             if( pString )
1397*cdf0e10cSrcweir                             {
1398*cdf0e10cSrcweir                                 OString aEnt = pString->getFilteredString();
1399*cdf0e10cSrcweir                                 if( aEnt.getLength() == 32 )
1400*cdf0e10cSrcweir                                     rtl_copyMemory( m_pData->m_aUEntry, aEnt.getStr(), 32 );
1401*cdf0e10cSrcweir                                 #if OSL_DEBUG_LEVEL > 1
1402*cdf0e10cSrcweir                                 else
1403*cdf0e10cSrcweir                                 {
1404*cdf0e10cSrcweir                                     fprintf( stderr, "U entry has length %d, should be 32 <", (int)aEnt.getLength() );
1405*cdf0e10cSrcweir                                     for( int i = 0; i < aEnt.getLength(); i++ )
1406*cdf0e10cSrcweir                                         fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) );
1407*cdf0e10cSrcweir                                     fprintf( stderr, ">\n" );
1408*cdf0e10cSrcweir                                 }
1409*cdf0e10cSrcweir                                 #endif
1410*cdf0e10cSrcweir                             }
1411*cdf0e10cSrcweir                         }
1412*cdf0e10cSrcweir                         if( r_ent != pDict->m_aMap.end() )
1413*cdf0e10cSrcweir                         {
1414*cdf0e10cSrcweir                             PDFNumber* pNum = dynamic_cast<PDFNumber*>(r_ent->second);
1415*cdf0e10cSrcweir                             if( pNum )
1416*cdf0e10cSrcweir                                 m_pData->m_nStandardRevision = static_cast<sal_uInt32>(pNum->m_fValue);
1417*cdf0e10cSrcweir                         }
1418*cdf0e10cSrcweir                         if( p_ent != pDict->m_aMap.end() )
1419*cdf0e10cSrcweir                         {
1420*cdf0e10cSrcweir                             PDFNumber* pNum = dynamic_cast<PDFNumber*>(p_ent->second);
1421*cdf0e10cSrcweir                             if( pNum )
1422*cdf0e10cSrcweir                                 m_pData->m_nPEntry = static_cast<sal_uInt32>(static_cast<sal_Int32>(pNum->m_fValue));
1423*cdf0e10cSrcweir                             #if OSL_DEBUG_LEVEL > 1
1424*cdf0e10cSrcweir                             fprintf( stderr, "p entry is %p\n", (void*)m_pData->m_nPEntry );
1425*cdf0e10cSrcweir                             #endif
1426*cdf0e10cSrcweir                         }
1427*cdf0e10cSrcweir                         #if OSL_DEBUG_LEVEL > 1
1428*cdf0e10cSrcweir                         fprintf( stderr, "Encryption dict: sec handler: %s, version = %d, revision = %d, key length = %d\n",
1429*cdf0e10cSrcweir                                  pFilter ? OUStringToOString( pFilter->getFilteredName(), RTL_TEXTENCODING_UTF8 ).getStr() : "<unknown>",
1430*cdf0e10cSrcweir                                  (int)m_pData->m_nAlgoVersion, (int)m_pData->m_nStandardRevision, (int)m_pData->m_nKeyLength );
1431*cdf0e10cSrcweir                         #endif
1432*cdf0e10cSrcweir                         break;
1433*cdf0e10cSrcweir                     }
1434*cdf0e10cSrcweir                 }
1435*cdf0e10cSrcweir             }
1436*cdf0e10cSrcweir         }
1437*cdf0e10cSrcweir     }
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir     return m_pData;
1440*cdf0e10cSrcweir }
1441*cdf0e10cSrcweir 
1442*cdf0e10cSrcweir bool PDFFile::emit( EmitContext& rWriteContext ) const
1443*cdf0e10cSrcweir {
1444*cdf0e10cSrcweir     setEmitData(  rWriteContext, new EmitImplData( this ) );
1445*cdf0e10cSrcweir 
1446*cdf0e10cSrcweir     OStringBuffer aBuf( 32 );
1447*cdf0e10cSrcweir     aBuf.append( "%PDF-" );
1448*cdf0e10cSrcweir     aBuf.append( sal_Int32( m_nMajor ) );
1449*cdf0e10cSrcweir     aBuf.append( '.' );
1450*cdf0e10cSrcweir     aBuf.append( sal_Int32( m_nMinor ) );
1451*cdf0e10cSrcweir     aBuf.append( "\n" );
1452*cdf0e10cSrcweir     if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
1453*cdf0e10cSrcweir         return false;
1454*cdf0e10cSrcweir     return emitSubElements( rWriteContext );
1455*cdf0e10cSrcweir }
1456*cdf0e10cSrcweir 
1457*cdf0e10cSrcweir PDFEntry* PDFFile::clone() const
1458*cdf0e10cSrcweir {
1459*cdf0e10cSrcweir     PDFFile* pNewFl = new PDFFile();
1460*cdf0e10cSrcweir     pNewFl->m_nMajor = m_nMajor;
1461*cdf0e10cSrcweir     pNewFl->m_nMinor = m_nMinor;
1462*cdf0e10cSrcweir     cloneSubElements( pNewFl->m_aSubElements );
1463*cdf0e10cSrcweir     return pNewFl;
1464*cdf0e10cSrcweir }
1465*cdf0e10cSrcweir 
1466*cdf0e10cSrcweir PDFPart::~PDFPart()
1467*cdf0e10cSrcweir {
1468*cdf0e10cSrcweir }
1469*cdf0e10cSrcweir 
1470*cdf0e10cSrcweir bool PDFPart::emit( EmitContext& rWriteContext ) const
1471*cdf0e10cSrcweir {
1472*cdf0e10cSrcweir     return emitSubElements( rWriteContext );
1473*cdf0e10cSrcweir }
1474*cdf0e10cSrcweir 
1475*cdf0e10cSrcweir PDFEntry* PDFPart::clone() const
1476*cdf0e10cSrcweir {
1477*cdf0e10cSrcweir     PDFPart* pNewPt = new PDFPart();
1478*cdf0e10cSrcweir     cloneSubElements( pNewPt->m_aSubElements );
1479*cdf0e10cSrcweir     return pNewPt;
1480*cdf0e10cSrcweir }
1481*cdf0e10cSrcweir 
1482