1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sdext.hxx"
26 
27 #include "imagecontainer.hxx"
28 #include "genericelements.hxx"
29 #include "xmlemitter.hxx"
30 
31 #include <rtl/ustrbuf.hxx>
32 #include <osl/file.h>
33 #include <rtl/crc.h>
34 
35 #include <com/sun/star/graphic/XGraphicProvider.hpp>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 
38 #include <cppuhelper/implbase1.hxx>
39 #include <comphelper/stl_types.hxx>
40 
41 #include <boost/bind.hpp>
42 
43 using namespace com::sun::star;
44 
45 namespace pdfi
46 {
47 
48 namespace
49 {
50 
51 static const sal_Char aBase64EncodeTable[] =
52     { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
53       'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
54       'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
55       'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
56       '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
57 
encodeBase64(const sal_Int8 * i_pBuffer,const sal_uInt32 i_nBufferLength)58 rtl::OUString encodeBase64( const sal_Int8* i_pBuffer, const sal_uInt32 i_nBufferLength )
59 {
60     rtl::OUStringBuffer aBuf( (i_nBufferLength+1) * 4 / 3 );
61     const sal_Int32 nRemain(i_nBufferLength%3);
62     const sal_Int32 nFullTripleLength( i_nBufferLength - (i_nBufferLength%3));
63     sal_Int32 nBufPos( 0 );
64     for( sal_Int32 i = 0; i < nFullTripleLength; i += 3, nBufPos += 4 )
65 	{
66         const sal_Int32 nBinary = (((sal_uInt8)i_pBuffer[i + 0]) << 16) +
67                                   (((sal_uInt8)i_pBuffer[i + 1]) <<  8) +
68                                   ((sal_uInt8)i_pBuffer[i + 2]);
69 
70         aBuf.appendAscii("====");
71 
72         sal_uInt8 nIndex (static_cast<sal_uInt8>((nBinary & 0xFC0000) >> 18));
73         aBuf.setCharAt(nBufPos, aBase64EncodeTable [nIndex]);
74 
75         nIndex = static_cast<sal_uInt8>((nBinary & 0x3F000) >> 12);
76         aBuf.setCharAt(nBufPos+1, aBase64EncodeTable [nIndex]);
77 
78         nIndex = static_cast<sal_uInt8>((nBinary & 0xFC0) >> 6);
79         aBuf.setCharAt(nBufPos+2, aBase64EncodeTable [nIndex]);
80 
81         nIndex = static_cast<sal_uInt8>((nBinary & 0x3F));
82         aBuf.setCharAt(nBufPos+3, aBase64EncodeTable [nIndex]);
83 	}
84     if( nRemain > 0 )
85     {
86         aBuf.appendAscii("====");
87         sal_Int32 nBinary( 0 );
88         const sal_Int32 nStart(i_nBufferLength-nRemain);
89         switch(nRemain)
90         {
91             case 1: nBinary = ((sal_uInt8)i_pBuffer[nStart + 0]) << 16;
92                 break;
93             case 2: nBinary = (((sal_uInt8)i_pBuffer[nStart + 0]) << 16) +
94                               (((sal_uInt8)i_pBuffer[nStart + 1]) <<  8);
95                 break;
96         }
97         sal_uInt8 nIndex (static_cast<sal_uInt8>((nBinary & 0xFC0000) >> 18));
98         aBuf.setCharAt(nBufPos, aBase64EncodeTable [nIndex]);
99 
100         nIndex = static_cast<sal_uInt8>((nBinary & 0x3F000) >> 12);
101         aBuf.setCharAt(nBufPos+1, aBase64EncodeTable [nIndex]);
102 
103         if( nRemain == 2 )
104         {
105             nIndex = static_cast<sal_uInt8>((nBinary & 0xFC0) >> 6);
106             aBuf.setCharAt(nBufPos+2, aBase64EncodeTable [nIndex]);
107         }
108     }
109 
110     return aBuf.makeStringAndClear();
111 }
112 
113 } // namespace
114 
ImageContainer()115 ImageContainer::ImageContainer() :
116     m_aImages()
117 {}
118 
addImage(const uno::Sequence<beans::PropertyValue> & xBitmap)119 ImageId ImageContainer::addImage( const uno::Sequence<beans::PropertyValue>& xBitmap )
120 {
121     m_aImages.push_back( xBitmap );
122     return m_aImages.size()-1;
123 }
124 
writeBase64EncodedStream(ImageId nId,EmitContext & rContext)125 void ImageContainer::writeBase64EncodedStream( ImageId nId, EmitContext& rContext )
126 {
127     OSL_ASSERT( nId >= 0 && nId < ImageId( m_aImages.size()) );
128 
129     const uno::Sequence<beans::PropertyValue>& rEntry( m_aImages[nId] );
130 
131     // find "InputSequence" property
132     const beans::PropertyValue* pAry(rEntry.getConstArray());
133     const sal_Int32             nLen(rEntry.getLength());
134     const beans::PropertyValue* pValue(
135         std::find_if(pAry,pAry+nLen,
136                      boost::bind(comphelper::TPropertyValueEqualFunctor(),
137                                  _1,
138                                  rtl::OUString::createFromAscii("InputSequence"))));
139     OSL_ENSURE( pValue != pAry+nLen,
140                 "InputSequence not found" );
141 
142     uno::Sequence<sal_Int8> aData;
143     if( !(pValue->Value >>= aData) )
144         OSL_ENSURE(false,"Wrong data type");
145 
146     rContext.rEmitter.write( encodeBase64( aData.getConstArray(), aData.getLength() ));
147 }
148 
149 }
150