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 "SlsBitmapCompressor.hxx"
28 
29 #include <tools/stream.hxx>
30 #include <vcl/bitmapex.hxx>
31 #include <vcl/pngread.hxx>
32 #include <vcl/pngwrite.hxx>
33 
34 namespace sd { namespace slidesorter { namespace cache {
35 
36 
37 //===== NoBitmapCompression ===================================================
38 
39 /** This dummy replacement simply stores a shared pointer to the original
40     preview bitmap.
41 */
42 class NoBitmapCompression::DummyReplacement
43     : public BitmapReplacement
44 {
45 public:
46     Bitmap maPreview;
47     Size maOriginalSize;
48 
DummyReplacement(const Bitmap & rPreview)49     DummyReplacement (const Bitmap& rPreview) : maPreview(rPreview)  { }
~DummyReplacement(void)50     virtual ~DummyReplacement(void) {}
GetMemorySize(void) const51     virtual sal_Int32 GetMemorySize (void) const { return maPreview.GetSizeBytes(); }
52 };
53 
54 
55 
Compress(const Bitmap & rBitmap) const56 ::boost::shared_ptr<BitmapReplacement> NoBitmapCompression::Compress (const Bitmap& rBitmap) const
57 {
58     return ::boost::shared_ptr<BitmapReplacement>(new DummyReplacement(rBitmap));
59 }
60 
Decompress(const BitmapReplacement & rBitmapData) const61 Bitmap NoBitmapCompression::Decompress (const BitmapReplacement& rBitmapData) const
62 {
63     return dynamic_cast<const DummyReplacement&>(rBitmapData).maPreview;
64 }
65 
66 
67 
68 
IsLossless(void) const69 bool NoBitmapCompression::IsLossless (void) const
70 {
71     return true;
72 }
73 
74 
75 
76 
77 //===== CompressionByDeletion =================================================
78 
Compress(const Bitmap &) const79 ::boost::shared_ptr<BitmapReplacement> CompressionByDeletion::Compress (const Bitmap& ) const
80 {
81     return ::boost::shared_ptr<BitmapReplacement>();
82 }
83 
84 
85 
86 
Decompress(const BitmapReplacement &) const87 Bitmap CompressionByDeletion::Decompress (const BitmapReplacement& ) const
88 {
89     // Return a NULL pointer.  This will eventually lead to a request for
90     // the creation of a new one.
91     return Bitmap();
92 }
93 
94 
95 
96 
IsLossless(void) const97 bool CompressionByDeletion::IsLossless (void) const
98 {
99     return false;
100 }
101 
102 
103 
104 
105 //===== ResolutionReduction ===================================================
106 
107 /** Store a scaled down bitmap together with the original size.
108 */
109 class ResolutionReduction::ResolutionReducedReplacement : public BitmapReplacement
110 {
111 public:
112     Bitmap maPreview;
113     Size maOriginalSize;
114 
115     virtual ~ResolutionReducedReplacement();
116     virtual sal_Int32 GetMemorySize (void) const;
117 };
118 
~ResolutionReducedReplacement()119 ResolutionReduction::ResolutionReducedReplacement::~ResolutionReducedReplacement()
120 {
121 }
122 
GetMemorySize(void) const123 sal_Int32 ResolutionReduction::ResolutionReducedReplacement::GetMemorySize (void) const
124 {
125     return maPreview.GetSizeBytes();
126 }
127 
Compress(const Bitmap & rBitmap) const128 ::boost::shared_ptr<BitmapReplacement> ResolutionReduction::Compress (
129     const Bitmap& rBitmap) const
130 {
131     ResolutionReducedReplacement* pResult = new ResolutionReducedReplacement();
132     pResult->maPreview = rBitmap;
133     Size aSize (rBitmap.GetSizePixel());
134     pResult->maOriginalSize = aSize;
135     if (aSize.Width()>0 && aSize.Width()<mnWidth)
136     {
137         int nHeight = aSize.Height() * mnWidth / aSize.Width() ;
138         pResult->maPreview.Scale(Size(mnWidth,nHeight));
139     }
140 
141     return ::boost::shared_ptr<BitmapReplacement>(pResult);
142 }
143 
144 
145 
146 
Decompress(const BitmapReplacement & rBitmapData) const147 Bitmap ResolutionReduction::Decompress (const BitmapReplacement& rBitmapData) const
148 {
149     Bitmap aResult;
150 
151     const ResolutionReducedReplacement* pData (
152         dynamic_cast<const ResolutionReducedReplacement*>(&rBitmapData));
153 
154     if ( ! pData->maPreview.IsEmpty())
155     {
156         aResult = pData->maPreview;
157         if (pData->maOriginalSize.Width() > mnWidth)
158             aResult.Scale(pData->maOriginalSize);
159     }
160 
161     return aResult;
162 }
163 
164 
165 
166 
IsLossless(void) const167 bool ResolutionReduction::IsLossless (void) const
168 {
169     return false;
170 }
171 
172 
173 
174 
175 //===== PNGCompression ========================================================
176 
177 
178 class PngCompression::PngReplacement : public BitmapReplacement
179 {
180 public:
181     void* mpData;
182     sal_Int32 mnDataSize;
183     Size maImageSize;
PngReplacement(void)184     PngReplacement (void)
185         : mpData(NULL),
186           mnDataSize(0),
187           maImageSize(0,0)
188     {}
~PngReplacement(void)189     virtual ~PngReplacement (void)
190     {
191         delete [] (char*)mpData;
192     }
GetMemorySize(void) const193     virtual sal_Int32 GetMemorySize (void) const
194     {
195         return mnDataSize;
196     }
197 };
198 
199 
200 
201 
Compress(const Bitmap & rBitmap) const202 ::boost::shared_ptr<BitmapReplacement> PngCompression::Compress (const Bitmap& rBitmap) const
203 {
204     ::vcl::PNGWriter aWriter (rBitmap);
205     SvMemoryStream aStream (32768, 32768);
206     aWriter.Write(aStream);
207 
208     PngReplacement* pResult = new PngReplacement();
209     pResult->maImageSize = rBitmap.GetSizePixel();
210     pResult->mnDataSize = aStream.Tell();
211     pResult->mpData = new char[pResult->mnDataSize];
212     memcpy(pResult->mpData, aStream.GetData(), pResult->mnDataSize);
213 
214     return ::boost::shared_ptr<BitmapReplacement>(pResult);
215 }
216 
217 
218 
219 
Decompress(const BitmapReplacement & rBitmapData) const220 Bitmap PngCompression::Decompress (
221     const BitmapReplacement& rBitmapData) const
222 {
223     Bitmap aResult;
224     const PngReplacement* pData (dynamic_cast<const PngReplacement*>(&rBitmapData));
225     if (pData != NULL)
226     {
227         SvMemoryStream aStream (pData->mpData, pData->mnDataSize, STREAM_READ);
228         ::vcl::PNGReader aReader (aStream);
229         aResult = aReader.Read().GetBitmap();
230     }
231 
232     return aResult;
233 }
234 
235 
236 
237 
IsLossless(void) const238 bool PngCompression::IsLossless (void) const
239 {
240     return true;
241 }
242 
243 
244 
245 
246 } } } // end of namespace ::sd::slidesorter::cache
247