Line data Source code
1 :
2 : /* Copyright (c) 2010-2016, Cedric Stalder <cedric.stalder@gmail.com>
3 : * Stefan Eilemann <eile@eyescale.ch>
4 : *
5 : * This file is part of Pression <https://github.com/Eyescale/Pression>
6 : *
7 : * This library is free software; you can redistribute it and/or modify it under
8 : * the terms of the GNU Lesser General Public License version 2.1 as published
9 : * by the Free Software Foundation.
10 : *
11 : * This library is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 : * details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with this library; if not, write to the Free Software Foundation, Inc.,
18 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : */
20 :
21 : #include "compressor.h"
22 :
23 : #include "compressorInfo.h"
24 : #include "compressorResult.h"
25 : #include "log.h"
26 : #include "plugin.h"
27 : #include "pluginInstance.h"
28 : #include "pluginRegistry.h"
29 :
30 : #include <algorithm>
31 :
32 : namespace pression
33 : {
34 : namespace detail
35 : {
36 : class Compressor : public PluginInstance
37 : {
38 : public:
39 1 : Compressor() {}
40 :
41 185 : Compressor( pression::PluginRegistry& registry, const uint32_t name )
42 185 : {
43 185 : setup( registry, name );
44 185 : }
45 :
46 186 : ~Compressor() { clear(); }
47 :
48 371 : void clear()
49 : {
50 371 : if( instance )
51 185 : plugin->deleteCompressor( instance );
52 371 : PluginInstance::clear();
53 371 : }
54 :
55 185 : bool setup( pression::PluginRegistry& registry, const uint32_t name )
56 : {
57 185 : if( instance && info.name == name )
58 0 : return true;
59 :
60 185 : clear();
61 :
62 185 : if( name <= EQ_COMPRESSOR_NONE )
63 0 : return true;
64 :
65 185 : plugin = registry.findPlugin( name );
66 185 : LBASSERT( plugin );
67 185 : if( !plugin )
68 0 : return false;
69 :
70 185 : instance = plugin->newCompressor( name );
71 185 : info = plugin->findInfo( name );
72 185 : LBASSERT( instance );
73 185 : LBASSERT( info.name == name );
74 185 : LBLOG( LOG_PLUGIN ) << "Instantiated compressor of type 0x" << std::hex
75 185 : << name << std::dec << std::endl;
76 185 : return instance;
77 : }
78 : };
79 : }
80 :
81 1 : Compressor::Compressor()
82 1 : : impl_( new detail::Compressor )
83 : {
84 1 : LB_TS_THREAD( _thread );
85 1 : }
86 :
87 185 : Compressor::Compressor( PluginRegistry& registry, const uint32_t name )
88 185 : : impl_( new detail::Compressor( registry, name ))
89 : {
90 185 : LB_TS_THREAD( _thread );
91 185 : }
92 :
93 372 : Compressor::~Compressor()
94 : {
95 186 : delete impl_;
96 186 : }
97 :
98 927 : bool Compressor::isGood() const
99 : {
100 1854 : LB_TS_SCOPED( _thread );
101 1854 : return impl_->isGood() && impl_->instance;
102 : }
103 :
104 0 : bool Compressor::uses( const uint32_t name ) const
105 : {
106 0 : return isGood() && impl_->info.name == name;
107 : }
108 :
109 0 : const EqCompressorInfo& Compressor::getInfo() const
110 : {
111 0 : return impl_->info;
112 : }
113 :
114 0 : uint32_t Compressor::choose( const PluginRegistry& registry,
115 : const uint32_t tokenType, const float minQuality,
116 : const bool ignoreAlpha )
117 : {
118 0 : LBASSERT( tokenType != EQ_COMPRESSOR_DATATYPE_NONE );
119 0 : CompressorInfo candidate;
120 0 : candidate.name = EQ_COMPRESSOR_NONE;
121 0 : candidate.ratingAlpha = 1.0f;
122 0 : candidate.quality = 1.0f;
123 0 : candidate.speed = 1.0f;
124 :
125 0 : const Plugins& plugins = registry.getPlugins();
126 0 : for( const Plugin* plugin : plugins )
127 : {
128 0 : const CompressorInfos& infos = plugin->getInfos();
129 0 : for( const CompressorInfo& info : infos )
130 : {
131 0 : if( info.tokenType != tokenType || info.quality < minQuality ||
132 0 : ( info.capabilities & EQ_COMPRESSOR_TRANSFER ))
133 : {
134 0 : continue;
135 : }
136 :
137 0 : const float rating = ignoreAlpha ? info.ratingNoAlpha :
138 0 : info.ratingAlpha;
139 0 : if( rating > candidate.ratingAlpha )
140 : {
141 0 : candidate = info;
142 0 : candidate.ratingAlpha = rating;
143 : }
144 : }
145 : }
146 0 : return candidate.name;
147 : }
148 :
149 0 : bool Compressor::setup( PluginRegistry& registry, const uint32_t name )
150 : {
151 0 : return impl_->setup( registry, name );
152 : }
153 :
154 0 : bool Compressor::setup( PluginRegistry& registry, const uint32_t tokenType,
155 : const float minQuality, const bool ignoreMSE )
156 : {
157 0 : return impl_->setup( registry,
158 0 : choose( registry, tokenType, minQuality, ignoreMSE ));
159 : }
160 :
161 0 : bool Compressor::realloc()
162 : {
163 0 : if( !isGood( ))
164 0 : return false;
165 :
166 0 : impl_->plugin->deleteCompressor( impl_->instance );
167 0 : impl_->instance = impl_->plugin->newCompressor( impl_->info.name );
168 :
169 0 : LBASSERT( impl_->instance );
170 0 : return impl_->instance;
171 : }
172 :
173 0 : void Compressor::clear()
174 : {
175 0 : impl_->clear();
176 0 : }
177 :
178 370 : void Compressor::compress( void* const in, const uint64_t pvpIn[4],
179 : const uint64_t flags )
180 : {
181 370 : LBASSERT( impl_->plugin );
182 370 : LBASSERT( impl_->instance );
183 370 : LBASSERT( in );
184 370 : if( !isGood( ))
185 0 : return;
186 :
187 370 : impl_->plugin->compress( impl_->instance, impl_->info.name, in, pvpIn,
188 370 : flags );
189 : }
190 :
191 0 : void Compressor::compress( void* const in, const uint64_t inDims[2] )
192 : {
193 0 : LBASSERT( impl_->plugin );
194 0 : LBASSERT( impl_->instance );
195 0 : LBASSERT( in );
196 0 : if( !isGood( ))
197 0 : return;
198 :
199 0 : impl_->plugin->compress( impl_->instance, impl_->info.name, in, inDims,
200 0 : EQ_COMPRESSOR_DATA_1D );
201 : }
202 :
203 0 : unsigned Compressor::getNumResults() const
204 : {
205 0 : LBASSERT( impl_->plugin );
206 0 : LBASSERT( impl_->instance );
207 0 : if( !isGood( ))
208 0 : return 0;
209 :
210 0 : return impl_->plugin->getNumResults( impl_->instance, impl_->info.name );
211 : }
212 :
213 0 : void Compressor::getResult( const unsigned i, void** const out,
214 : uint64_t* const outSize ) const
215 : {
216 0 : LBASSERT( impl_->plugin );
217 0 : LBASSERT( impl_->instance );
218 0 : if( !isGood( ))
219 0 : return;
220 :
221 0 : impl_->plugin->getResult( impl_->instance, impl_->info.name, i,
222 0 : out, outSize );
223 : }
224 :
225 185 : CompressorResult Compressor::getResult() const
226 : {
227 185 : LBASSERT( impl_->plugin );
228 185 : LBASSERT( impl_->instance );
229 185 : if( !isGood( ))
230 0 : return CompressorResult();
231 :
232 370 : const unsigned num = impl_->plugin->getNumResults( impl_->instance,
233 370 : impl_->info.name );
234 370 : CompressorChunks chunks;
235 185 : chunks.reserve( num );
236 :
237 553 : for( unsigned i = 0; i < num; ++i )
238 : {
239 : void* data;
240 : uint64_t size;
241 368 : impl_->plugin->getResult( impl_->instance, impl_->info.name, i,
242 368 : &data, &size );
243 368 : chunks.push_back( CompressorChunk( data, size ));
244 : }
245 :
246 185 : return CompressorResult( impl_->info.name, chunks );
247 : }
248 :
249 3 : }
|