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 library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #include "compressorRLEB.h"
20 : #include <limits>
21 :
22 : namespace
23 : {
24 : static const uint8_t _rleMarker = 0x42; // just a random number
25 : }
26 :
27 : #include "compressorRLE.ipp"
28 :
29 : namespace pression
30 : {
31 : namespace plugin
32 : {
33 : namespace
34 : {
35 3 : REGISTER_ENGINE( CompressorRLEB, BYTE, BYTE, 1., 0.97, 1., false );
36 : }
37 :
38 : template< typename T >
39 278 : inline void _compressChunk( const T* const in, const eq_uint64_t nPixels,
40 : Compressor::Result* result )
41 : {
42 278 : if( nPixels == 0 )
43 : {
44 0 : result->setSize( 0 );
45 0 : return;
46 : }
47 :
48 278 : T* tokenOut = reinterpret_cast< T* >( result->getData( ));
49 18750 : T tokenLast( in[0] );
50 18750 : T tokenSame( 1 );
51 18750 : T token(0);
52 :
53 29445902 : for( eq_uint64_t i = 1; i < nPixels; ++i )
54 : {
55 29445465 : token = in[i];
56 29445465 : COMPRESS( token );
57 : }
58 :
59 437 : WRITE_OUTPUT( token );
60 437 : result->setSize( (tokenOut - reinterpret_cast< T* >( result->getData( ))) *
61 : sizeof( T ));
62 : #ifndef PRESSION_AGGRESSIVE_CACHING
63 437 : result->pack();
64 : #endif
65 : }
66 :
67 : template< typename T >
68 74 : ssize_t _compress( const void* const inData, const eq_uint64_t nPixels,
69 : Compressor::ResultVector& results )
70 : {
71 74 : const eq_uint64_t size = nPixels * sizeof( T );
72 74 : const ssize_t nChunks = _setupResults( 1, size, results );
73 74 : const float width = static_cast< float >( nPixels ) /
74 74 : static_cast< float >( nChunks );
75 :
76 74 : const T* const data = reinterpret_cast< const T* >( inData );
77 :
78 316 : #pragma omp parallel for
79 242 : for( ssize_t i = 0; i < static_cast< ssize_t >( nChunks ) ; ++i )
80 : {
81 332 : const eq_uint64_t startIndex = static_cast< eq_uint64_t >( i * width );
82 :
83 : eq_uint64_t nextIndex;
84 332 : if ( i == nChunks - 1 )
85 74 : nextIndex = nPixels;
86 : else
87 258 : nextIndex = static_cast< eq_uint64_t >(( i + 1 ) * width );
88 332 : const eq_uint64_t chunkSize = ( nextIndex - startIndex );
89 :
90 332 : _compressChunk< T >( &data[ startIndex ], chunkSize, results[i] );
91 : }
92 74 : return nChunks;
93 : }
94 :
95 :
96 74 : void CompressorRLEB::compress( const void* const inData,
97 : const eq_uint64_t nPixels, const bool /*alpha*/ )
98 : {
99 74 : if( (nPixels & 0x7) == 0 )
100 36 : _nResults = _compress< eq_uint64_t >( inData, nPixels>>3, _results );
101 38 : else if( (nPixels & 0x3) == 0 )
102 12 : _nResults = _compress< uint32_t >( inData, nPixels>>2, _results );
103 26 : else if( (nPixels & 0x1) == 0 )
104 14 : _nResults = _compress< uint16_t >( inData, nPixels>>1, _results );
105 : else
106 12 : _nResults = _compress< uint8_t >( inData, nPixels, _results );
107 74 : }
108 :
109 : //----------------------------------------------------------------------
110 : template< typename T >
111 439 : inline void _decompressChunk( const T* in, T* out, const eq_uint64_t nPixels )
112 : {
113 439 : T token(0);
114 439 : T tokenLeft(0);
115 :
116 30486260 : for( eq_uint64_t i = 0; i < nPixels ; ++i )
117 : {
118 30485821 : if( tokenLeft == 0 )
119 : {
120 29932927 : token = *in; ++in;
121 29932927 : if( token == _rleMarker )
122 : {
123 181776 : token = *in; ++in;
124 181776 : tokenLeft = *in; ++in;
125 : }
126 : else // single symbol
127 29751151 : tokenLeft = 1;
128 : }
129 :
130 30485821 : --tokenLeft;
131 30485821 : out[i] = token;
132 : }
133 439 : }
134 :
135 :
136 : template< typename T >
137 74 : void _decompress( const void* const* inData, const unsigned nInputs,
138 : void* const outData, const eq_uint64_t nPixels )
139 : {
140 74 : const float width = static_cast< float >( nPixels ) /
141 74 : static_cast< float >( nInputs );
142 :
143 74 : const T* const* in = reinterpret_cast< const T* const* >( inData );
144 :
145 310 : #pragma omp parallel for
146 236 : for( ssize_t i = 0; i < static_cast< ssize_t >( nInputs ) ; ++i )
147 : {
148 334 : const eq_uint64_t startIndex = static_cast<uint64_t>( i * width );
149 :
150 : eq_uint64_t nextIndex;
151 334 : if ( i == static_cast<ssize_t>( nInputs -1 ) )
152 74 : nextIndex = nPixels;
153 : else
154 260 : nextIndex = static_cast< eq_uint64_t >(( i + 1 ) * width );
155 :
156 334 : const eq_uint64_t chunkSize = ( nextIndex - startIndex );
157 334 : T* out = reinterpret_cast< T* >( outData ) + startIndex;
158 :
159 334 : _decompressChunk< T >( in[i], out, chunkSize );
160 : }
161 74 : }
162 :
163 74 : void CompressorRLEB::decompress( const void* const* inData,
164 : const eq_uint64_t* const /*inSizes*/,
165 : const unsigned nInputs, void* const outData,
166 : eq_uint64_t* const outDims,
167 : const eq_uint64_t flags, void* const )
168 : {
169 74 : const eq_uint64_t nPixels = ( flags & EQ_COMPRESSOR_DATA_1D) ?
170 74 : outDims[1] : outDims[1] * outDims[3];
171 74 : if( (nPixels & 0x7) == 0 )
172 36 : _decompress< uint64_t >( inData, nInputs, outData, nPixels>>3 );
173 38 : else if( (nPixels & 0x3) == 0 )
174 12 : _decompress< uint32_t >( inData, nInputs, outData, nPixels>>2 );
175 26 : else if( (nPixels & 0x1) == 0 )
176 14 : _decompress< uint16_t >( inData, nInputs, outData, nPixels>>1 );
177 : else
178 12 : _decompress< uint8_t >( inData, nInputs, outData, nPixels );
179 74 : }
180 :
181 : }
182 3 : }
|