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 : #include "SlsBitmapCompressor.hxx"
21 :
22 : #include <tools/stream.hxx>
23 : #include <vcl/bitmapex.hxx>
24 : #include <vcl/pngread.hxx>
25 : #include <vcl/pngwrite.hxx>
26 :
27 : namespace sd { namespace slidesorter { namespace cache {
28 :
29 : //===== NoBitmapCompression ===================================================
30 :
31 : /** This dummy replacement simply stores a shared pointer to the original
32 : preview bitmap.
33 : */
34 : class NoBitmapCompression::DummyReplacement
35 : : public BitmapReplacement
36 : {
37 : public:
38 : Bitmap maPreview;
39 : Size maOriginalSize;
40 :
41 0 : DummyReplacement (const Bitmap& rPreview) : maPreview(rPreview) { }
42 0 : virtual ~DummyReplacement() {}
43 0 : virtual sal_Int32 GetMemorySize() const SAL_OVERRIDE { return maPreview.GetSizeBytes(); }
44 : };
45 :
46 0 : ::boost::shared_ptr<BitmapReplacement> NoBitmapCompression::Compress (const Bitmap& rBitmap) const
47 : {
48 0 : return ::boost::shared_ptr<BitmapReplacement>(new DummyReplacement(rBitmap));
49 : }
50 :
51 0 : Bitmap NoBitmapCompression::Decompress (const BitmapReplacement& rBitmapData) const
52 : {
53 0 : return dynamic_cast<const DummyReplacement&>(rBitmapData).maPreview;
54 : }
55 :
56 0 : bool NoBitmapCompression::IsLossless() const
57 : {
58 0 : return true;
59 : }
60 :
61 : //===== CompressionByDeletion =================================================
62 :
63 0 : ::boost::shared_ptr<BitmapReplacement> CompressionByDeletion::Compress (const Bitmap& ) const
64 : {
65 0 : return ::boost::shared_ptr<BitmapReplacement>();
66 : }
67 :
68 0 : Bitmap CompressionByDeletion::Decompress (const BitmapReplacement& ) const
69 : {
70 : // Return a NULL pointer. This will eventually lead to a request for
71 : // the creation of a new one.
72 0 : return Bitmap();
73 : }
74 :
75 0 : bool CompressionByDeletion::IsLossless() const
76 : {
77 0 : return false;
78 : }
79 :
80 : //===== ResolutionReduction ===================================================
81 :
82 : /** Store a scaled down bitmap together with the original size.
83 : */
84 0 : class ResolutionReduction::ResolutionReducedReplacement : public BitmapReplacement
85 : {
86 : public:
87 : Bitmap maPreview;
88 : Size maOriginalSize;
89 :
90 : virtual ~ResolutionReducedReplacement();
91 : virtual sal_Int32 GetMemorySize() const SAL_OVERRIDE;
92 : };
93 :
94 0 : ResolutionReduction::ResolutionReducedReplacement::~ResolutionReducedReplacement()
95 : {
96 0 : }
97 :
98 0 : sal_Int32 ResolutionReduction::ResolutionReducedReplacement::GetMemorySize() const
99 : {
100 0 : return maPreview.GetSizeBytes();
101 : }
102 :
103 0 : ::boost::shared_ptr<BitmapReplacement> ResolutionReduction::Compress (
104 : const Bitmap& rBitmap) const
105 : {
106 0 : ResolutionReducedReplacement* pResult = new ResolutionReducedReplacement();
107 0 : pResult->maPreview = rBitmap;
108 0 : Size aSize (rBitmap.GetSizePixel());
109 0 : pResult->maOriginalSize = aSize;
110 0 : if (aSize.Width()>0 && aSize.Width()<mnWidth)
111 : {
112 0 : int nHeight = aSize.Height() * mnWidth / aSize.Width() ;
113 0 : pResult->maPreview.Scale(Size(mnWidth,nHeight));
114 : }
115 :
116 0 : return ::boost::shared_ptr<BitmapReplacement>(pResult);
117 : }
118 :
119 0 : Bitmap ResolutionReduction::Decompress (const BitmapReplacement& rBitmapData) const
120 : {
121 0 : Bitmap aResult;
122 :
123 : const ResolutionReducedReplacement* pData (
124 0 : dynamic_cast<const ResolutionReducedReplacement*>(&rBitmapData));
125 :
126 0 : if ( pData && ! pData->maPreview.IsEmpty())
127 : {
128 0 : aResult = pData->maPreview;
129 0 : if (pData->maOriginalSize.Width() > mnWidth)
130 0 : aResult.Scale(pData->maOriginalSize);
131 : }
132 :
133 0 : return aResult;
134 : }
135 :
136 0 : bool ResolutionReduction::IsLossless() const
137 : {
138 0 : return false;
139 : }
140 :
141 : //===== PNGCompression ========================================================
142 :
143 : class PngCompression::PngReplacement : public BitmapReplacement
144 : {
145 : public:
146 : void* mpData;
147 : sal_Int32 mnDataSize;
148 : Size maImageSize;
149 0 : PngReplacement()
150 : : mpData(NULL),
151 : mnDataSize(0),
152 0 : maImageSize(0,0)
153 0 : {}
154 0 : virtual ~PngReplacement()
155 0 : {
156 0 : delete [] static_cast<char*>(mpData);
157 0 : }
158 0 : virtual sal_Int32 GetMemorySize() const SAL_OVERRIDE
159 : {
160 0 : return mnDataSize;
161 : }
162 : };
163 :
164 0 : ::boost::shared_ptr<BitmapReplacement> PngCompression::Compress (const Bitmap& rBitmap) const
165 : {
166 0 : vcl::PNGWriter aWriter (rBitmap);
167 0 : SvMemoryStream aStream (32768, 32768);
168 0 : aWriter.Write(aStream);
169 :
170 0 : PngReplacement* pResult = new PngReplacement();
171 0 : pResult->maImageSize = rBitmap.GetSizePixel();
172 0 : pResult->mnDataSize = aStream.Tell();
173 0 : pResult->mpData = new char[pResult->mnDataSize];
174 0 : memcpy(pResult->mpData, aStream.GetData(), pResult->mnDataSize);
175 :
176 0 : return ::boost::shared_ptr<BitmapReplacement>(pResult);
177 : }
178 :
179 0 : Bitmap PngCompression::Decompress (
180 : const BitmapReplacement& rBitmapData) const
181 : {
182 0 : Bitmap aResult;
183 0 : const PngReplacement* pData (dynamic_cast<const PngReplacement*>(&rBitmapData));
184 0 : if (pData != NULL)
185 : {
186 0 : SvMemoryStream aStream (pData->mpData, pData->mnDataSize, StreamMode::READ);
187 0 : vcl::PNGReader aReader (aStream);
188 0 : aResult = aReader.Read().GetBitmap();
189 : }
190 :
191 0 : return aResult;
192 : }
193 :
194 0 : bool PngCompression::IsLossless() const
195 : {
196 0 : return true;
197 : }
198 :
199 : } } } // end of namespace ::sd::slidesorter::cache
200 :
201 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|