@@ -15,8 +15,8 @@ namespace Zeiss.PiWeb.Volume.Block;
15
15
16
16
using System ;
17
17
using System . Buffers ;
18
- using System . IO ;
19
18
using System . Runtime . InteropServices ;
19
+ using System . Runtime . Intrinsics ;
20
20
using System . Threading ;
21
21
using System . Threading . Tasks ;
22
22
@@ -41,37 +41,49 @@ internal static void Decode( byte[] data,
41
41
IProgress < VolumeSliceDefinition > ? progress = null ,
42
42
CancellationToken ct = default )
43
43
{
44
- var reader = new BinaryReader ( new MemoryStream ( data ) ) ;
45
- var ( _, sizeX , sizeY , sizeZ , quantization ) = BlockVolumeMetaData . Read ( reader ) ;
44
+ var header = BlockVolumeMetaData . Create ( data ) ;
45
+ var ( _, sizeX , sizeY , sizeZ , quantization ) = header ;
46
46
var ( bcx , bcy , bcz ) = BlockVolume . GetBlockCount ( sizeX , sizeY , sizeZ ) ;
47
47
var blockCount = bcx * bcy ;
48
48
var encodedBlockInfos = new EncodedBlockInfo [ blockCount ] ;
49
+ var position = BlockVolumeMetaData . HeaderLength ;
50
+ var dataSpan = data . AsSpan ( ) ;
51
+
52
+ Quantization . Invert ( quantization ) ;
49
53
50
54
for ( ushort biz = 0 ; biz < bcz ; biz ++ )
51
55
{
52
56
ct . ThrowIfCancellationRequested ( ) ;
53
57
54
- var layerLength = reader . ReadInt32 ( ) ;
58
+ var layerLength = MemoryMarshal . Read < int > ( dataSpan . Slice ( position , sizeof ( int ) ) ) ;
59
+ position += sizeof ( int ) ;
55
60
if ( layerPredicate ? . Invoke ( biz ) is false )
56
61
{
57
- reader . BaseStream . Seek ( layerLength , SeekOrigin . Current ) ;
62
+ position += layerLength ;
58
63
continue ;
59
64
}
60
65
61
- ReadBlockInfos ( reader , blockCount , encodedBlockInfos ) ;
66
+ ReadLayer ( dataSpan , position , blockCount , encodedBlockInfos ) ;
62
67
DecodeLayer ( data , encodedBlockInfos , bcx , bcy , biz , quantization , blockPredicate , blockAction ) ;
63
68
64
69
progress ? . Report ( new VolumeSliceDefinition ( Direction . Z , ( ushort ) ( biz * BlockVolume . N ) ) ) ;
70
+
71
+ position += layerLength ;
65
72
}
66
73
}
67
74
68
- private static void ReadBlockInfos ( BinaryReader reader , int blockCount , EncodedBlockInfo [ ] encodedBlockInfos )
75
+ private static void ReadLayer ( ReadOnlySpan < byte > dataSpan , int position , int blockCount , EncodedBlockInfo [ ] encodedBlockInfos )
69
76
{
70
77
for ( var i = 0 ; i < blockCount ; i ++ )
71
78
{
72
- var encodedBlockInfo = EncodedBlockInfo . Read ( reader ) ;
73
- reader . BaseStream . Seek ( encodedBlockInfo . Info . Length , SeekOrigin . Current ) ;
79
+ var value = MemoryMarshal . Read < ushort > ( dataSpan [ position .. ] ) ;
80
+
81
+ position += sizeof ( ushort ) ;
82
+
83
+ var encodedBlockInfo = new EncodedBlockInfo ( position , BlockInfo . Create ( value ) ) ;
74
84
encodedBlockInfos [ i ] = encodedBlockInfo ;
85
+
86
+ position += encodedBlockInfo . Info . Length ;
75
87
}
76
88
}
77
89
@@ -85,18 +97,29 @@ private static void DecodeLayer(
85
97
BlockPredicate ? blockPredicate ,
86
98
BlockAction blockAction )
87
99
{
100
+ #if DEBUG
101
+ var buffers = ( ArrayPool < double > . Shared . Rent ( BlockVolume . N3 ) ,
102
+ ArrayPool < double > . Shared . Rent ( BlockVolume . N3 ) ,
103
+ ArrayPool < byte > . Shared . Rent ( BlockVolume . N3 ) ) ;
104
+ for ( var index = 0 ; index < blockCountX * blockCountY ; index ++ )
105
+ #else
88
106
Parallel . For ( 0 , blockCountX * blockCountY , ( ) => (
89
107
ArrayPool < double > . Shared . Rent ( BlockVolume . N3 ) ,
90
108
ArrayPool < double > . Shared . Rent ( BlockVolume . N3 ) ,
91
109
ArrayPool < byte > . Shared . Rent ( BlockVolume . N3 )
92
110
) , ( index , _ , buffers ) =>
111
+ #endif
93
112
{
94
113
var blockIndexX = index % blockCountX ;
95
114
var blockIndexY = index / blockCountX ;
96
115
var blockIndex = new BlockIndex ( ( ushort ) blockIndexX , ( ushort ) blockIndexY , blockIndexZ ) ;
97
116
98
117
if ( blockPredicate ? . Invoke ( blockIndex ) == false )
118
+ #if DEBUG
119
+ continue ;
120
+ #else
99
121
return buffers ;
122
+ #endif
100
123
101
124
var doubleBuffer1 = buffers . Item1 . AsSpan ( 0 , BlockVolume . N3 ) ;
102
125
var doubleBuffer2 = buffers . Item2 . AsSpan ( 0 , BlockVolume . N3 ) ;
@@ -109,18 +132,27 @@ private static void DecodeLayer(
109
132
//2. ZigZag
110
133
ZigZag . Reverse ( doubleBuffer1 , doubleBuffer2 ) ;
111
134
135
+ var nonEmptyVectors = FindNonEmptyVectors ( doubleBuffer2 ) ;
136
+
112
137
//3. Quantization
113
138
Quantization . Apply ( quantization . AsSpan ( ) , doubleBuffer2 ) ;
114
139
115
140
//4. Cosine transform
116
- DiscreteCosineTransform . Transform ( doubleBuffer2 , doubleBuffer1 , true ) ;
141
+ DiscreteCosineTransform . Transform ( doubleBuffer2 , doubleBuffer1 , true , nonEmptyVectors ) ;
117
142
118
143
//5. Discretization
119
144
for ( var i = 0 ; i < BlockVolume . N3 ; i ++ )
120
145
byteBuffer [ i ] = ( byte ) Math . Clamp ( doubleBuffer1 [ i ] , byte . MinValue , byte . MaxValue ) ;
121
146
122
147
blockAction ( byteBuffer , blockIndex ) ;
123
148
149
+ #if DEBUG
150
+ }
151
+
152
+ ArrayPool < double > . Shared . Return ( buffers . Item1 ) ;
153
+ ArrayPool < double > . Shared . Return ( buffers . Item2 ) ;
154
+ ArrayPool < byte > . Shared . Return ( buffers . Item3 ) ;
155
+ #else
124
156
return buffers ;
125
157
} ,
126
158
buffers =>
@@ -129,6 +161,21 @@ private static void DecodeLayer(
129
161
ArrayPool < double > . Shared . Return ( buffers . Item2 ) ;
130
162
ArrayPool < byte > . Shared . Return ( buffers . Item3 ) ;
131
163
} ) ;
164
+ #endif
165
+ }
166
+
167
+ private static ulong FindNonEmptyVectors ( Span < double > values )
168
+ {
169
+ var vectors = MemoryMarshal . Cast < double , Vector512 < double > > ( values ) ;
170
+ var result = 0UL ;
171
+
172
+ for ( ushort i = 0 ; i < BlockVolume . N2 ; i ++ )
173
+ {
174
+ if ( Vector512 . Sum ( Vector512 . Abs ( vectors [ i ] ) ) > 1e-12 )
175
+ result |= 1UL << i ;
176
+ }
177
+
178
+ return result ;
132
179
}
133
180
134
181
private static void ReadBlock ( ReadOnlySpan < byte > data , EncodedBlockInfo blockInfo , Span < double > result )
@@ -167,23 +214,7 @@ private static void ReadBlock( ReadOnlySpan<byte> data, EncodedBlockInfo blockIn
167
214
168
215
#endregion
169
216
170
- private readonly record struct EncodedBlockInfo ( int StartIndex , BlockInfo Info )
171
- {
172
- #region methods
173
-
174
- /// <summary>
175
- /// Reads the encoded block info from the specified <paramref name="reader"/>
176
- /// </summary>
177
- public static EncodedBlockInfo Read ( BinaryReader reader )
178
- {
179
- var info = BlockInfo . Read ( reader ) ;
180
- var startIndex = ( int ) reader . BaseStream . Position ;
181
-
182
- return new EncodedBlockInfo ( startIndex , info ) ;
183
- }
184
-
185
- #endregion
186
- }
217
+ private readonly record struct EncodedBlockInfo ( int StartIndex , BlockInfo Info ) ;
187
218
188
219
internal delegate void BlockAction ( ReadOnlySpan < byte > data , BlockIndex index ) ;
189
220
0 commit comments