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_sd.hxx"
26 
27 #include "SlsCacheCompactor.hxx"
28 
29 #include "SlsBitmapCompressor.hxx"
30 #include "SlsBitmapCache.hxx"
31 #include "SlsCacheCompactor.hxx"
32 #include "SlsCacheConfiguration.hxx"
33 
34 #include <rtl/ustring.hxx>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <set>
37 
38 using namespace ::com::sun::star::uno;
39 
40 // Uncomment the definition of VERBOSE to get some more OSL_TRACE messages.
41 #ifdef DEBUG
42 //#define VERBOSE
43 #endif
44 
45 namespace {
46 
47 /** This is a trivial implementation of the CacheCompactor interface class.
48     It ignores calls to RequestCompaction() and thus will never decrease the
49     total size of off-screen preview bitmaps.
50 */
51 class NoCacheCompaction
52     : public ::sd::slidesorter::cache::CacheCompactor
53 {
54 public:
NoCacheCompaction(::sd::slidesorter::cache::BitmapCache & rCache,sal_Int32 nMaximalCacheSize)55     NoCacheCompaction (
56         ::sd::slidesorter::cache::BitmapCache& rCache,
57         sal_Int32 nMaximalCacheSize)
58         : CacheCompactor(rCache, nMaximalCacheSize)
59     {}
60 
RequestCompaction(void)61     virtual void RequestCompaction (void) { /* Ignored */ };
62 
63 protected:
Run(void)64     virtual void Run (void) { /* Do nothing */ };
65 };
66 
67 
68 
69 
70 /** This implementation of the CacheCompactor interface class uses one of
71     several bitmap compression algorithms to reduce the number of the bytes
72     of the off-screen previews in the bitmap cache.  See the documentation
73     of CacheCompactor::Create() for more details on configuration properties
74     that control the choice of compression algorithm.
75 */
76 class CacheCompactionByCompression
77     : public ::sd::slidesorter::cache::CacheCompactor
78 {
79 public:
80     CacheCompactionByCompression (
81         ::sd::slidesorter::cache::BitmapCache& rCache,
82         sal_Int32 nMaximalCacheSize,
83         const ::boost::shared_ptr< ::sd::slidesorter::cache::BitmapCompressor>& rpCompressor);
84 
85 protected:
86     virtual void Run (void);
87 
88 private:
89     ::boost::shared_ptr< ::sd::slidesorter::cache::BitmapCompressor>  mpCompressor;
90 };
91 
92 
93 } // end of anonymous namespace
94 
95 namespace sd { namespace slidesorter { namespace cache {
96 
97 
Create(BitmapCache & rCache,sal_Int32 nMaximalCacheSize)98 ::std::auto_ptr<CacheCompactor> CacheCompactor::Create (
99     BitmapCache& rCache,
100     sal_Int32 nMaximalCacheSize)
101 {
102     static const ::rtl::OUString sNone (RTL_CONSTASCII_USTRINGPARAM("None"));
103     static const ::rtl::OUString sCompress (RTL_CONSTASCII_USTRINGPARAM("Compress"));
104     static const ::rtl::OUString sErase (RTL_CONSTASCII_USTRINGPARAM("Erase"));
105     static const ::rtl::OUString sResolution (RTL_CONSTASCII_USTRINGPARAM("ResolutionReduction"));
106     static const ::rtl::OUString sPNGCompression (RTL_CONSTASCII_USTRINGPARAM("PNGCompression"));
107 
108     ::boost::shared_ptr<BitmapCompressor> pCompressor;
109     ::rtl::OUString sCompressionPolicy(sPNGCompression);
110     Any aCompressionPolicy (CacheConfiguration::Instance()->GetValue(
111         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CompressionPolicy"))));
112     if (aCompressionPolicy.has<rtl::OUString>())
113         aCompressionPolicy >>= sCompressionPolicy;
114     if (sCompressionPolicy == sNone)
115         pCompressor.reset(new NoBitmapCompression());
116     else if (sCompressionPolicy == sErase)
117         pCompressor.reset(new CompressionByDeletion());
118     else if (sCompressionPolicy == sResolution)
119         pCompressor.reset(new ResolutionReduction());
120     else
121         pCompressor.reset(new PngCompression());
122 
123     ::std::auto_ptr<CacheCompactor> pCompactor (NULL);
124     ::rtl::OUString sCompactionPolicy(sCompress);
125     Any aCompactionPolicy (CacheConfiguration::Instance()->GetValue(
126         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CompactionPolicy"))));
127     if (aCompactionPolicy.has<rtl::OUString>())
128         aCompactionPolicy >>= sCompactionPolicy;
129     if (sCompactionPolicy == sNone)
130         pCompactor.reset(new NoCacheCompaction(rCache,nMaximalCacheSize));
131     else
132         pCompactor.reset(new CacheCompactionByCompression(rCache,nMaximalCacheSize,pCompressor));
133 
134     return pCompactor;
135 }
136 
137 
138 
139 
RequestCompaction(void)140 void CacheCompactor::RequestCompaction (void)
141 {
142     if ( ! mbIsCompactionRunning && ! maCompactionTimer.IsActive())
143         maCompactionTimer.Start();
144 }
145 
146 
147 
148 
CacheCompactor(BitmapCache & rCache,sal_Int32 nMaximalCacheSize)149 CacheCompactor::CacheCompactor(
150     BitmapCache& rCache,
151     sal_Int32 nMaximalCacheSize)
152     : mrCache(rCache),
153       mnMaximalCacheSize(nMaximalCacheSize),
154       mbIsCompactionRunning(false)
155 {
156     maCompactionTimer.SetTimeout(100 /*ms*/);
157     maCompactionTimer.SetTimeoutHdl(LINK(this,CacheCompactor,CompactionCallback));
158 
159 }
160 
161 
162 
163 
IMPL_LINK(CacheCompactor,CompactionCallback,Timer *,EMPTYARG)164 IMPL_LINK(CacheCompactor, CompactionCallback, Timer*, EMPTYARG)
165 {
166     mbIsCompactionRunning = true;
167 
168     try
169     {
170         Run();
171     }
172     catch(::com::sun::star::uno::RuntimeException e) { }
173     catch(::com::sun::star::uno::Exception e) { }
174 
175     mbIsCompactionRunning = false;
176     return 1;
177 }
178 
179 
180 
181 
182 } } } // end of namespace ::sd::slidesorter::cache
183 
184 
185 
186 
187 namespace {
188 
189 //===== CacheCompactionByCompression ==========================================
190 
CacheCompactionByCompression(::sd::slidesorter::cache::BitmapCache & rCache,sal_Int32 nMaximalCacheSize,const::boost::shared_ptr<::sd::slidesorter::cache::BitmapCompressor> & rpCompressor)191 CacheCompactionByCompression::CacheCompactionByCompression (
192     ::sd::slidesorter::cache::BitmapCache& rCache,
193     sal_Int32 nMaximalCacheSize,
194     const ::boost::shared_ptr< ::sd::slidesorter::cache::BitmapCompressor>& rpCompressor)
195     : CacheCompactor(rCache,nMaximalCacheSize),
196       mpCompressor(rpCompressor)
197 {
198 }
199 
200 
201 
202 
Run(void)203 void CacheCompactionByCompression::Run (void)
204 {
205     if (mrCache.GetSize() > mnMaximalCacheSize)
206     {
207 #ifdef VERBOSE
208 		OSL_TRACE ("bitmap cache uses to much space: %d > %d",
209             mrCache.GetSize(), mnMaximalCacheSize);
210 #endif
211 
212         ::std::auto_ptr< ::sd::slidesorter::cache::BitmapCache::CacheIndex> pIndex (
213             mrCache.GetCacheIndex(false,false));
214         ::sd::slidesorter::cache::BitmapCache::CacheIndex::iterator iIndex;
215         for (iIndex=pIndex->begin(); iIndex!=pIndex->end(); ++iIndex)
216         {
217             if (*iIndex == NULL)
218                 continue;
219 
220             mrCache.Compress(*iIndex, mpCompressor);
221             if (mrCache.GetSize() < mnMaximalCacheSize)
222                 break;
223         }
224         mrCache.ReCalculateTotalCacheSize();
225 #ifdef VERBOSE
226         OSL_TRACE ("    there are now %d bytes occupied", mrCache.GetSize());
227 #endif
228     }
229 }
230 
231 
232 } // end of anonymous namespace
233