Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "SlsBitmapCache.hxx"
22 : #include "SlsCacheCompactor.hxx"
23 : #include "SlsBitmapCompressor.hxx"
24 : #include "SlsCacheConfiguration.hxx"
25 :
26 : #include "sdpage.hxx"
27 : #include "drawdoc.hxx"
28 :
29 : // Define the default value for the maximal cache size that is used for
30 : // previews that are currently not visible. The visible previews are all
31 : // held in memory at all times. This default is used only when the
32 : // configuration does not have a value.
33 : static const sal_Int32 MAXIMAL_CACHE_SIZE = 4L*1024L*1024L;
34 :
35 : using namespace ::com::sun::star::uno;
36 :
37 : namespace sd { namespace slidesorter { namespace cache {
38 :
39 0 : class BitmapCache::CacheEntry
40 : {
41 : public:
42 : CacheEntry(const Bitmap& rBitmap, sal_Int32 nLastAccessTime, bool bIsPrecious);
43 : CacheEntry(sal_Int32 nLastAccessTime, bool bIsPrecious);
44 0 : ~CacheEntry (void) {};
45 : inline void Recycle (const CacheEntry& rEntry);
46 : inline sal_Int32 GetMemorySize (void) const;
47 : void Compress (const ::boost::shared_ptr<BitmapCompressor>& rpCompressor);
48 : inline void Decompress (void);
49 :
50 0 : bool IsUpToDate (void) const { return mbIsUpToDate; }
51 0 : void SetUpToDate (bool bIsUpToDate) { mbIsUpToDate = bIsUpToDate; }
52 0 : sal_Int32 GetAccessTime (void) const { return mnLastAccessTime; }
53 0 : void SetAccessTime (sal_Int32 nAccessTime) { mnLastAccessTime = nAccessTime; }
54 :
55 0 : Bitmap GetPreview (void) const { return maPreview; }
56 : inline void SetPreview (const Bitmap& rPreview);
57 : bool HasPreview (void) const;
58 :
59 0 : Bitmap GetMarkedPreview (void) const { return maMarkedPreview; }
60 : inline void SetMarkedPreview (const Bitmap& rMarkePreview);
61 :
62 0 : bool HasReplacement (void) const { return (mpReplacement.get() != NULL); }
63 : inline bool HasLosslessReplacement (void) const;
64 : void Clear (void) { maPreview.SetEmpty(); maMarkedPreview.SetEmpty();
65 : mpReplacement.reset(); mpCompressor.reset(); }
66 0 : void Invalidate (void) { mpReplacement.reset(); mpCompressor.reset(); mbIsUpToDate = false; }
67 0 : bool IsPrecious (void) const { return mbIsPrecious; }
68 0 : void SetPrecious (bool bIsPrecious) { mbIsPrecious = bIsPrecious; }
69 :
70 : private:
71 : Bitmap maPreview;
72 : Bitmap maMarkedPreview;
73 : ::boost::shared_ptr<BitmapReplacement> mpReplacement;
74 : ::boost::shared_ptr<BitmapCompressor> mpCompressor;
75 : Size maBitmapSize;
76 : bool mbIsUpToDate;
77 : sal_Int32 mnLastAccessTime;
78 : // When this flag is set then the bitmap is not modified by a cache
79 : // compactor.
80 : bool mbIsPrecious;
81 : };
82 : class CacheEntry;
83 :
84 : class CacheHash {
85 : public:
86 0 : size_t operator()(const BitmapCache::CacheKey& p) const
87 0 : { return (size_t)p; }
88 : };
89 :
90 0 : class BitmapCache::CacheBitmapContainer
91 : : public ::boost::unordered_map<CacheKey, CacheEntry, CacheHash>
92 : {
93 : public:
94 0 : CacheBitmapContainer (void) {}
95 : };
96 :
97 : namespace {
98 :
99 : typedef ::std::vector<
100 : ::std::pair< ::sd::slidesorter::cache::BitmapCache::CacheKey,
101 : ::sd::slidesorter::cache::BitmapCache::CacheEntry>
102 : > SortableBitmapContainer;
103 :
104 : /** Compare elements of the bitmap cache according to their last access
105 : time.
106 : */
107 : class AccessTimeComparator
108 : {
109 : public:
110 0 : bool operator () (
111 : const SortableBitmapContainer::value_type& e1,
112 : const SortableBitmapContainer::value_type& e2)
113 : {
114 0 : return e1.second.GetAccessTime() < e2.second.GetAccessTime();
115 : }
116 : };
117 :
118 :
119 : } // end of anonymous namespace
120 :
121 :
122 : //===== BitmapCache =========================================================
123 :
124 0 : BitmapCache::BitmapCache (const sal_Int32 nMaximalNormalCacheSize)
125 : : maMutex(),
126 0 : mpBitmapContainer(new CacheBitmapContainer()),
127 : mnNormalCacheSize(0),
128 : mnPreciousCacheSize(0),
129 : mnCurrentAccessTime(0),
130 : mnMaximalNormalCacheSize(MAXIMAL_CACHE_SIZE),
131 : mpCacheCompactor(),
132 0 : mbIsFull(false)
133 : {
134 0 : if (nMaximalNormalCacheSize > 0)
135 0 : mnMaximalNormalCacheSize = nMaximalNormalCacheSize;
136 : else
137 : {
138 0 : Any aCacheSize (CacheConfiguration::Instance()->GetValue("CacheSize"));
139 0 : if (aCacheSize.has<sal_Int32>())
140 0 : aCacheSize >>= mnMaximalNormalCacheSize;
141 : }
142 :
143 0 : mpCacheCompactor = CacheCompactor::Create(*this,mnMaximalNormalCacheSize);
144 0 : }
145 :
146 :
147 :
148 :
149 0 : BitmapCache::~BitmapCache (void)
150 : {
151 0 : Clear();
152 0 : }
153 :
154 :
155 :
156 :
157 0 : void BitmapCache::Clear (void)
158 : {
159 0 : ::osl::MutexGuard aGuard (maMutex);
160 :
161 0 : mpBitmapContainer->clear();
162 0 : mnNormalCacheSize = 0;
163 0 : mnPreciousCacheSize = 0;
164 0 : mnCurrentAccessTime = 0;
165 0 : }
166 :
167 :
168 :
169 :
170 0 : bool BitmapCache::IsFull (void) const
171 : {
172 0 : return mbIsFull;
173 : }
174 :
175 :
176 :
177 :
178 0 : sal_Int32 BitmapCache::GetSize (void)
179 : {
180 0 : return mnNormalCacheSize;
181 : }
182 :
183 :
184 :
185 :
186 0 : bool BitmapCache::HasBitmap (const CacheKey& rKey)
187 : {
188 0 : ::osl::MutexGuard aGuard (maMutex);
189 :
190 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
191 0 : return (iEntry != mpBitmapContainer->end()
192 0 : && (iEntry->second.HasPreview() || iEntry->second.HasReplacement()));
193 : }
194 :
195 :
196 :
197 :
198 0 : bool BitmapCache::BitmapIsUpToDate (const CacheKey& rKey)
199 : {
200 0 : ::osl::MutexGuard aGuard (maMutex);
201 :
202 0 : bool bIsUpToDate = false;
203 0 : CacheBitmapContainer::iterator aIterator (mpBitmapContainer->find(rKey));
204 0 : if (aIterator != mpBitmapContainer->end())
205 0 : bIsUpToDate = aIterator->second.IsUpToDate();
206 :
207 0 : return bIsUpToDate;
208 : }
209 :
210 :
211 :
212 :
213 0 : Bitmap BitmapCache::GetBitmap (const CacheKey& rKey)
214 : {
215 0 : ::osl::MutexGuard aGuard (maMutex);
216 :
217 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
218 0 : if (iEntry == mpBitmapContainer->end())
219 : {
220 : // Create an empty bitmap for the given key that acts as placeholder
221 : // until we are given the real one. Mark it as not being up to date.
222 0 : SetBitmap(rKey, Bitmap(), false);
223 0 : iEntry = mpBitmapContainer->find(rKey);
224 0 : iEntry->second.SetUpToDate(false);
225 : }
226 : else
227 : {
228 0 : iEntry->second.SetAccessTime(mnCurrentAccessTime++);
229 :
230 : // Maybe we have to decompress the preview.
231 0 : if ( ! iEntry->second.HasPreview() && iEntry->second.HasReplacement())
232 : {
233 0 : UpdateCacheSize(iEntry->second, REMOVE);
234 0 : iEntry->second.Decompress();
235 0 : UpdateCacheSize(iEntry->second, ADD);
236 : }
237 : }
238 0 : return iEntry->second.GetPreview();
239 : }
240 :
241 :
242 :
243 :
244 0 : Bitmap BitmapCache::GetMarkedBitmap (const CacheKey& rKey)
245 : {
246 0 : ::osl::MutexGuard aGuard (maMutex);
247 :
248 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
249 0 : if (iEntry != mpBitmapContainer->end())
250 : {
251 0 : iEntry->second.SetAccessTime(mnCurrentAccessTime++);
252 0 : return iEntry->second.GetMarkedPreview();
253 : }
254 : else
255 0 : return Bitmap();
256 : }
257 :
258 :
259 :
260 :
261 0 : void BitmapCache::ReleaseBitmap (const CacheKey& rKey)
262 : {
263 0 : ::osl::MutexGuard aGuard (maMutex);
264 :
265 0 : CacheBitmapContainer::iterator aIterator (mpBitmapContainer->find(rKey));
266 0 : if (aIterator != mpBitmapContainer->end())
267 : {
268 0 : UpdateCacheSize(aIterator->second, REMOVE);
269 0 : mpBitmapContainer->erase(aIterator);
270 0 : }
271 0 : }
272 :
273 :
274 :
275 :
276 0 : bool BitmapCache::InvalidateBitmap (const CacheKey& rKey)
277 : {
278 0 : ::osl::MutexGuard aGuard (maMutex);
279 :
280 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
281 0 : if (iEntry != mpBitmapContainer->end())
282 : {
283 0 : iEntry->second.SetUpToDate(false);
284 :
285 : // When there is a preview then we release the replacement. The
286 : // preview itself is kept until a new one is created.
287 0 : if (iEntry->second.HasPreview())
288 : {
289 0 : UpdateCacheSize(iEntry->second, REMOVE);
290 0 : iEntry->second.Invalidate();
291 0 : UpdateCacheSize(iEntry->second, ADD);
292 : }
293 0 : return true;
294 : }
295 : else
296 0 : return false;
297 : }
298 :
299 :
300 :
301 :
302 0 : void BitmapCache::InvalidateCache (void)
303 : {
304 0 : ::osl::MutexGuard aGuard (maMutex);
305 :
306 0 : CacheBitmapContainer::iterator iEntry;
307 0 : for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
308 : {
309 0 : iEntry->second.Invalidate();
310 : }
311 0 : ReCalculateTotalCacheSize();
312 0 : }
313 :
314 :
315 :
316 :
317 0 : void BitmapCache::SetBitmap (
318 : const CacheKey& rKey,
319 : const Bitmap& rPreview,
320 : bool bIsPrecious)
321 : {
322 0 : ::osl::MutexGuard aGuard (maMutex);
323 :
324 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
325 0 : if (iEntry != mpBitmapContainer->end())
326 : {
327 0 : UpdateCacheSize(iEntry->second, REMOVE);
328 0 : iEntry->second.SetPreview(rPreview);
329 0 : iEntry->second.SetUpToDate(true);
330 0 : iEntry->second.SetAccessTime(mnCurrentAccessTime++);
331 : }
332 : else
333 : {
334 0 : iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
335 : rKey,
336 : CacheEntry(rPreview, mnCurrentAccessTime++, bIsPrecious))
337 0 : ).first;
338 : }
339 :
340 0 : if (iEntry != mpBitmapContainer->end())
341 0 : UpdateCacheSize(iEntry->second, ADD);
342 0 : }
343 :
344 :
345 :
346 :
347 0 : void BitmapCache::SetMarkedBitmap (
348 : const CacheKey& rKey,
349 : const Bitmap& rPreview)
350 : {
351 0 : ::osl::MutexGuard aGuard (maMutex);
352 :
353 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
354 0 : if (iEntry != mpBitmapContainer->end())
355 : {
356 0 : UpdateCacheSize(iEntry->second, REMOVE);
357 0 : iEntry->second.SetMarkedPreview(rPreview);
358 0 : iEntry->second.SetAccessTime(mnCurrentAccessTime++);
359 0 : UpdateCacheSize(iEntry->second, ADD);
360 0 : }
361 0 : }
362 :
363 :
364 :
365 :
366 0 : void BitmapCache::SetPrecious (const CacheKey& rKey, bool bIsPrecious)
367 : {
368 0 : ::osl::MutexGuard aGuard (maMutex);
369 :
370 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
371 0 : if (iEntry != mpBitmapContainer->end())
372 : {
373 0 : if (iEntry->second.IsPrecious() != bIsPrecious)
374 : {
375 0 : UpdateCacheSize(iEntry->second, REMOVE);
376 0 : iEntry->second.SetPrecious(bIsPrecious);
377 0 : UpdateCacheSize(iEntry->second, ADD);
378 : }
379 : }
380 0 : else if (bIsPrecious)
381 : {
382 0 : iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
383 : rKey,
384 : CacheEntry(Bitmap(), mnCurrentAccessTime++, bIsPrecious))
385 0 : ).first;
386 0 : UpdateCacheSize(iEntry->second, ADD);
387 0 : }
388 0 : }
389 :
390 :
391 :
392 :
393 0 : void BitmapCache::ReCalculateTotalCacheSize (void)
394 : {
395 0 : ::osl::MutexGuard aGuard (maMutex);
396 :
397 0 : mnNormalCacheSize = 0;
398 0 : mnPreciousCacheSize = 0;
399 0 : CacheBitmapContainer::iterator iEntry;
400 0 : for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
401 : {
402 0 : if (iEntry->second.IsPrecious())
403 0 : mnPreciousCacheSize += iEntry->second.GetMemorySize();
404 : else
405 0 : mnNormalCacheSize += iEntry->second.GetMemorySize();
406 : }
407 0 : mbIsFull = (mnNormalCacheSize >= mnMaximalNormalCacheSize);
408 :
409 0 : SAL_INFO("sd.sls", OSL_THIS_FUNC << ": cache size is " << mnNormalCacheSize << "/" << mnPreciousCacheSize);
410 0 : }
411 :
412 :
413 :
414 :
415 0 : void BitmapCache::Recycle (const BitmapCache& rCache)
416 : {
417 0 : ::osl::MutexGuard aGuard (maMutex);
418 :
419 0 : CacheBitmapContainer::const_iterator iOtherEntry;
420 0 : for (iOtherEntry=rCache.mpBitmapContainer->begin();
421 0 : iOtherEntry!=rCache.mpBitmapContainer->end();
422 : ++iOtherEntry)
423 : {
424 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(iOtherEntry->first));
425 0 : if (iEntry == mpBitmapContainer->end())
426 : {
427 0 : iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
428 0 : iOtherEntry->first,
429 : CacheEntry(mnCurrentAccessTime++, true))
430 0 : ).first;
431 0 : UpdateCacheSize(iEntry->second, ADD);
432 : }
433 0 : if (iEntry != mpBitmapContainer->end())
434 : {
435 0 : UpdateCacheSize(iEntry->second, REMOVE);
436 0 : iEntry->second.Recycle(iOtherEntry->second);
437 0 : UpdateCacheSize(iEntry->second, ADD);
438 : }
439 0 : }
440 0 : }
441 :
442 :
443 :
444 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
445 0 : ::std::auto_ptr<BitmapCache::CacheIndex> BitmapCache::GetCacheIndex (
446 : bool bIncludePrecious,
447 : bool bIncludeNoPreview) const
448 : {
449 0 : ::osl::MutexGuard aGuard (maMutex);
450 :
451 : // Create a copy of the bitmap container.
452 0 : SortableBitmapContainer aSortedContainer;
453 0 : aSortedContainer.reserve(mpBitmapContainer->size());
454 :
455 : // Copy the relevant entries.
456 0 : CacheBitmapContainer::iterator iEntry;
457 0 : for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
458 : {
459 0 : if ( ! bIncludePrecious && iEntry->second.IsPrecious())
460 0 : continue;
461 :
462 0 : if ( ! bIncludeNoPreview && ! iEntry->second.HasPreview())
463 0 : continue;
464 :
465 : aSortedContainer.push_back(SortableBitmapContainer::value_type(
466 0 : iEntry->first,iEntry->second));
467 : }
468 :
469 : // Sort the remaining entries.
470 0 : ::std::sort(aSortedContainer.begin(), aSortedContainer.end(), AccessTimeComparator());
471 :
472 : // Return a list with the keys of the sorted entries.
473 0 : ::std::auto_ptr<CacheIndex> pIndex(new CacheIndex());
474 0 : SortableBitmapContainer::iterator iIndexEntry;
475 0 : pIndex->reserve(aSortedContainer.size());
476 0 : for (iIndexEntry=aSortedContainer.begin(); iIndexEntry!=aSortedContainer.end(); ++iIndexEntry)
477 0 : pIndex->push_back(iIndexEntry->first);
478 0 : return pIndex;
479 : }
480 : SAL_WNODEPRECATED_DECLARATIONS_POP
481 :
482 :
483 :
484 0 : void BitmapCache::Compress (
485 : const CacheKey& rKey,
486 : const ::boost::shared_ptr<BitmapCompressor>& rpCompressor)
487 : {
488 0 : ::osl::MutexGuard aGuard (maMutex);
489 :
490 0 : CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
491 0 : if (iEntry != mpBitmapContainer->end() && iEntry->second.HasPreview())
492 : {
493 0 : UpdateCacheSize(iEntry->second, REMOVE);
494 0 : iEntry->second.Compress(rpCompressor);
495 0 : UpdateCacheSize(iEntry->second, ADD);
496 0 : }
497 0 : }
498 :
499 :
500 :
501 :
502 0 : void BitmapCache::UpdateCacheSize (const CacheEntry& rEntry, CacheOperation eOperation)
503 : {
504 0 : sal_Int32 nEntrySize (rEntry.GetMemorySize());
505 0 : sal_Int32& rCacheSize (rEntry.IsPrecious() ? mnPreciousCacheSize : mnNormalCacheSize);
506 0 : switch (eOperation)
507 : {
508 : case ADD:
509 0 : rCacheSize += nEntrySize;
510 0 : if ( ! rEntry.IsPrecious() && mnNormalCacheSize>mnMaximalNormalCacheSize)
511 : {
512 0 : mbIsFull = true;
513 : SAL_INFO("sd.sls", OSL_THIS_FUNC << ": cache size is " << mnNormalCacheSize << " > " << mnMaximalNormalCacheSize);
514 0 : mpCacheCompactor->RequestCompaction();
515 : }
516 0 : break;
517 :
518 : case REMOVE:
519 0 : rCacheSize -= nEntrySize;
520 0 : if (mnNormalCacheSize < mnMaximalNormalCacheSize)
521 0 : mbIsFull = false;
522 0 : break;
523 :
524 : default:
525 : OSL_ASSERT(false);
526 0 : break;
527 : }
528 0 : }
529 :
530 :
531 :
532 :
533 : //===== CacheEntry ============================================================
534 :
535 0 : BitmapCache::CacheEntry::CacheEntry(
536 : sal_Int32 nLastAccessTime,
537 : bool bIsPrecious)
538 : : maPreview(),
539 : maMarkedPreview(),
540 : mbIsUpToDate(true),
541 : mnLastAccessTime(nLastAccessTime),
542 0 : mbIsPrecious(bIsPrecious)
543 : {
544 0 : }
545 :
546 :
547 :
548 :
549 0 : BitmapCache::CacheEntry::CacheEntry(
550 : const Bitmap& rPreview,
551 : sal_Int32 nLastAccessTime,
552 : bool bIsPrecious)
553 : : maPreview(rPreview),
554 : maMarkedPreview(),
555 : mbIsUpToDate(true),
556 : mnLastAccessTime(nLastAccessTime),
557 0 : mbIsPrecious(bIsPrecious)
558 : {
559 0 : }
560 :
561 :
562 :
563 :
564 0 : inline void BitmapCache::CacheEntry::Recycle (const CacheEntry& rEntry)
565 : {
566 0 : if ((rEntry.HasPreview() || rEntry.HasLosslessReplacement())
567 0 : && ! (HasPreview() || HasLosslessReplacement()))
568 : {
569 0 : maPreview = rEntry.maPreview;
570 0 : maMarkedPreview = rEntry.maMarkedPreview;
571 0 : mpReplacement = rEntry.mpReplacement;
572 0 : mpCompressor = rEntry.mpCompressor;
573 0 : mnLastAccessTime = rEntry.mnLastAccessTime;
574 0 : mbIsUpToDate = rEntry.mbIsUpToDate;
575 : }
576 0 : }
577 :
578 :
579 :
580 :
581 0 : inline sal_Int32 BitmapCache::CacheEntry::GetMemorySize (void) const
582 : {
583 0 : sal_Int32 nSize (0);
584 0 : nSize += maPreview.GetSizeBytes();
585 0 : nSize += maMarkedPreview.GetSizeBytes();
586 0 : if (mpReplacement.get() != NULL)
587 0 : nSize += mpReplacement->GetMemorySize();
588 0 : return nSize;
589 : }
590 :
591 :
592 :
593 :
594 0 : void BitmapCache::CacheEntry::Compress (const ::boost::shared_ptr<BitmapCompressor>& rpCompressor)
595 : {
596 0 : if ( ! maPreview.IsEmpty())
597 : {
598 0 : if (mpReplacement.get() == NULL)
599 : {
600 0 : mpReplacement = rpCompressor->Compress(maPreview);
601 :
602 : #if OSL_DEBUG_LEVEL > 2
603 : sal_uInt32 nOldSize (maPreview.GetSizeBytes());
604 : sal_uInt32 nNewSize (mpReplacement.get()!=NULL ? mpReplacement->GetMemorySize() : 0);
605 : if (nOldSize == 0)
606 : nOldSize = 1;
607 : sal_Int32 nRatio (100L * nNewSize / nOldSize);
608 : SAL_INFO("sd.sls", OSL_THIS_FUNC << ": compressing bitmap for " << %x << " from " << nOldSize << " to " << nNewSize << " bytes (" << nRatio << "%)");
609 : #endif
610 :
611 0 : mpCompressor = rpCompressor;
612 : }
613 :
614 0 : maPreview.SetEmpty();
615 0 : maMarkedPreview.SetEmpty();
616 : }
617 0 : }
618 :
619 :
620 :
621 :
622 0 : inline void BitmapCache::CacheEntry::Decompress (void)
623 : {
624 0 : if (mpReplacement.get()!=NULL && mpCompressor.get()!=NULL && maPreview.IsEmpty())
625 : {
626 0 : maPreview = mpCompressor->Decompress(*mpReplacement);
627 0 : maMarkedPreview.SetEmpty();
628 0 : if ( ! mpCompressor->IsLossless())
629 0 : mbIsUpToDate = false;
630 : }
631 0 : }
632 :
633 :
634 :
635 0 : inline void BitmapCache::CacheEntry::SetPreview (const Bitmap& rPreview)
636 : {
637 0 : maPreview = rPreview;
638 0 : maMarkedPreview.SetEmpty();
639 0 : mpReplacement.reset();
640 0 : mpCompressor.reset();
641 0 : }
642 :
643 :
644 :
645 :
646 0 : bool BitmapCache::CacheEntry::HasPreview (void) const
647 : {
648 0 : return ! maPreview.IsEmpty();
649 : }
650 :
651 :
652 :
653 :
654 0 : inline void BitmapCache::CacheEntry::SetMarkedPreview (const Bitmap& rMarkedPreview)
655 : {
656 0 : maMarkedPreview = rMarkedPreview;
657 0 : }
658 :
659 :
660 :
661 :
662 0 : inline bool BitmapCache::CacheEntry::HasLosslessReplacement (void) const
663 : {
664 0 : return mpReplacement.get()!=NULL
665 0 : && mpCompressor.get()!=NULL
666 0 : && mpCompressor->IsLossless();
667 : }
668 :
669 :
670 : } } } // end of namespace ::sd::slidesorter::cache
671 :
672 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|