Skip to content

Commit bb1f72e

Browse files
committed
Add AbstractBlockProcessor to reduce boiler-plate in BlockProcessor implementations
1 parent bdf4b7f commit bb1f72e

File tree

6 files changed

+238
-214
lines changed

6 files changed

+238
-214
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package net.imglib2.algorithm.blocks;
2+
3+
import static net.imglib2.util.Util.safeInt;
4+
5+
import java.util.Arrays;
6+
7+
import net.imglib2.Interval;
8+
import net.imglib2.algorithm.blocks.util.BlockProcessorSourceInterval;
9+
import net.imglib2.blocks.TempArray;
10+
import net.imglib2.type.PrimitiveType;
11+
import net.imglib2.util.Intervals;
12+
13+
/**
14+
* Boilerplate for {@link BlockProcessor} to simplify implementations.
15+
* <p>
16+
* This is intented as a base class for {@code BlockProcessor} that have source
17+
* dimensionality fixed at construction. For {@code BlockProcessor} with
18+
* adaptable number of dimensions (such as converters), see {@link
19+
* AbstractDimensionlessBlockProcessor}.
20+
* <p>
21+
* {@link BlockProcessor#getSourcePos() getSourcePos()}, {@link
22+
* BlockProcessor#getSourceSize() getSourceSize()}, and {@link
23+
* BlockProcessor#getSourceInterval() getSourceInterval()} are implemented to
24+
* return the {@code protected} fields {@code long[] sourcePos} and {@code
25+
* }int[] sourceSize}. The {@code }protected} method {@code }int sourceLength()}
26+
* can be used to get the number of elements in the source interval.
27+
* <p>
28+
* {@link BlockProcessor#getSourceBuffer() getSourceBuffer()} is implemented
29+
* according to the {@code sourcePrimitiveType} specified at construction.
30+
*
31+
* @param <I>
32+
* input primitive array type, e.g., float[]
33+
* @param <O>
34+
* output primitive array type, e.g., float[]
35+
*/
36+
public abstract class AbstractBlockProcessor< I, O > implements BlockProcessor< I, O >
37+
{
38+
private final TempArray< I > tempArray;
39+
40+
protected final long[] sourcePos;
41+
42+
protected final int[] sourceSize;
43+
44+
private final BlockProcessorSourceInterval sourceInterval = new BlockProcessorSourceInterval( this );
45+
46+
protected AbstractBlockProcessor( final PrimitiveType sourcePrimitiveType, final int numSourceDimensions )
47+
{
48+
tempArray = TempArray.forPrimitiveType( sourcePrimitiveType );
49+
sourcePos = new long[ numSourceDimensions ];
50+
sourceSize = new int[ numSourceDimensions ];
51+
}
52+
53+
protected AbstractBlockProcessor( final AbstractBlockProcessor< I, O > proc )
54+
{
55+
tempArray = proc.tempArray.newInstance();
56+
final int numSourceDimensions = proc.sourcePos.length;
57+
sourcePos = new long[ numSourceDimensions ];
58+
sourceSize = new int[ numSourceDimensions ];
59+
}
60+
61+
protected int sourceLength()
62+
{
63+
return safeInt( Intervals.numElements( sourceSize ) );
64+
}
65+
66+
@Override
67+
public void setTargetInterval( final Interval interval )
68+
{
69+
interval.min( sourcePos );
70+
Arrays.setAll( sourceSize, d -> safeInt( interval.dimension( d ) ) );
71+
}
72+
73+
@Override
74+
public long[] getSourcePos()
75+
{
76+
return sourcePos;
77+
}
78+
79+
@Override
80+
public int[] getSourceSize()
81+
{
82+
return sourceSize;
83+
}
84+
85+
@Override
86+
public Interval getSourceInterval()
87+
{
88+
return sourceInterval;
89+
}
90+
91+
@Override
92+
public I getSourceBuffer()
93+
{
94+
return tempArray.get( sourceLength() );
95+
}
96+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package net.imglib2.algorithm.blocks;
2+
3+
import static net.imglib2.util.Util.safeInt;
4+
5+
import java.util.Arrays;
6+
7+
import net.imglib2.Interval;
8+
import net.imglib2.algorithm.blocks.util.BlockProcessorSourceInterval;
9+
import net.imglib2.blocks.TempArray;
10+
import net.imglib2.type.PrimitiveType;
11+
import net.imglib2.util.Intervals;
12+
13+
/**
14+
* Boilerplate for {@link BlockProcessor} to simplify implementations.
15+
* <p>
16+
* This is intented as a base class for {@code BlockProcessor} with an adaptable
17+
* number of dimensions (such as converters). For {@code BlockProcessor} with a
18+
* fixed number of source dimensions, see {@link AbstractBlockProcessor}.
19+
* <p>
20+
* {@link BlockProcessor#getSourcePos() getSourcePos()}, {@link
21+
* BlockProcessor#getSourceSize() getSourceSize()}, and {@link
22+
* BlockProcessor#getSourceInterval() getSourceInterval()} are implemented to
23+
* return the {@code protected} fields {@code long[] sourcePos} and {@code
24+
* }int[] sourceSize}. The {@code }protected} method {@code }int sourceLength()}
25+
* can be used to get the number of elements in the source interval.
26+
* <p>
27+
* {@link BlockProcessor#getSourceBuffer() getSourceBuffer()} is implemented
28+
* according to the {@code sourcePrimitiveType} specified at construction.
29+
*
30+
* @param <I>
31+
* input primitive array type, e.g., float[]
32+
* @param <O>
33+
* output primitive array type, e.g., float[]
34+
*/
35+
public abstract class AbstractDimensionlessBlockProcessor< I, O > implements BlockProcessor< I, O >
36+
{
37+
private final TempArray< I > tempArray;
38+
39+
protected long[] sourcePos;
40+
41+
protected int[] sourceSize;
42+
43+
private final BlockProcessorSourceInterval sourceInterval = new BlockProcessorSourceInterval( this );
44+
45+
protected AbstractDimensionlessBlockProcessor( final PrimitiveType sourcePrimitiveType )
46+
{
47+
tempArray = TempArray.forPrimitiveType( sourcePrimitiveType );
48+
}
49+
50+
protected AbstractDimensionlessBlockProcessor( final AbstractDimensionlessBlockProcessor< I, O > proc )
51+
{
52+
tempArray = proc.tempArray.newInstance();
53+
}
54+
55+
@Override
56+
public void setTargetInterval( final Interval interval )
57+
{
58+
updateNumSourceDimsensions( interval.numDimensions() );
59+
interval.min( sourcePos );
60+
Arrays.setAll( sourceSize, d -> safeInt( interval.dimension( d ) ) );
61+
}
62+
63+
/**
64+
* Re-allocates {@code sourcePos} and {@code sourceSize} arrays if they do
65+
* not already exist and have {@code length==n}.
66+
*
67+
* @param n
68+
* new number of source dimensions
69+
*
70+
* @return {@code true} if {@code sourcePos} and {@code sourceSize} arrays were re-allocated
71+
*/
72+
protected boolean updateNumSourceDimsensions( final int n )
73+
{
74+
if ( sourcePos == null || sourcePos.length != n )
75+
{
76+
sourcePos = new long[ n ];
77+
sourceSize = new int[ n ];
78+
return true;
79+
}
80+
return false;
81+
}
82+
83+
protected int sourceLength()
84+
{
85+
return safeInt( Intervals.numElements( sourceSize ) );
86+
}
87+
88+
@Override
89+
public long[] getSourcePos()
90+
{
91+
return sourcePos;
92+
}
93+
94+
@Override
95+
public int[] getSourceSize()
96+
{
97+
return sourceSize;
98+
}
99+
100+
@Override
101+
public Interval getSourceInterval()
102+
{
103+
return sourceInterval;
104+
}
105+
106+
@Override
107+
public I getSourceBuffer()
108+
{
109+
return tempArray.get( sourceLength() );
110+
}
111+
}

src/main/java/net/imglib2/algorithm/blocks/convert/ConvertBlockProcessor.java

Lines changed: 7 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
* %%
1212
* Redistribution and use in source and binary forms, with or without
1313
* modification, are permitted provided that the following conditions are met:
14-
*
14+
*
1515
* 1. Redistributions of source code must retain the above copyright notice,
1616
* this list of conditions and the following disclaimer.
1717
* 2. Redistributions in binary form must reproduce the above copyright notice,
1818
* this list of conditions and the following disclaimer in the documentation
1919
* and/or other materials provided with the distribution.
20-
*
20+
*
2121
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2222
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2323
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,18 +33,11 @@
3333
*/
3434
package net.imglib2.algorithm.blocks.convert;
3535

36-
import static net.imglib2.util.Util.safeInt;
37-
38-
import java.util.Arrays;
39-
40-
import net.imglib2.Interval;
36+
import net.imglib2.algorithm.blocks.AbstractDimensionlessBlockProcessor;
4137
import net.imglib2.algorithm.blocks.BlockProcessor;
4238
import net.imglib2.algorithm.blocks.ClampType;
43-
import net.imglib2.algorithm.blocks.util.BlockProcessorSourceInterval;
4439
import net.imglib2.algorithm.blocks.util.UnaryOperatorType;
45-
import net.imglib2.blocks.TempArray;
4640
import net.imglib2.type.NativeType;
47-
import net.imglib2.util.Intervals;
4841

4942
/**
5043
* Convert primitive arrays between standard ImgLib2 {@code Type}s.
@@ -55,32 +48,20 @@
5548
* @param <O>
5649
* output primitive array type, e.g., float[]
5750
*/
58-
class ConvertBlockProcessor< I, O > implements BlockProcessor< I, O >
51+
class ConvertBlockProcessor< I, O > extends AbstractDimensionlessBlockProcessor< I, O >
5952
{
60-
private final TempArray< I > tempArray;
61-
6253
private final ConvertLoop< I, O > loop;
6354

64-
private long[] sourcePos;
65-
66-
private int[] sourceSize;
67-
68-
private int sourceLength;
69-
70-
private final BlockProcessorSourceInterval sourceInterval;
71-
7255
public < S extends NativeType< S >, T extends NativeType< T > > ConvertBlockProcessor( final S sourceType, final T targetType, final ClampType clamp )
7356
{
74-
tempArray = TempArray.forPrimitiveType( sourceType.getNativeTypeFactory().getPrimitiveType() );
57+
super( sourceType.getNativeTypeFactory().getPrimitiveType() );
7558
loop = ConvertLoops.get( UnaryOperatorType.of( sourceType, targetType ), clamp );
76-
sourceInterval = new BlockProcessorSourceInterval( this );
7759
}
7860

7961
private ConvertBlockProcessor( ConvertBlockProcessor< I, O > convert )
8062
{
81-
tempArray = convert.tempArray.newInstance();
63+
super( convert );
8264
loop = convert.loop;
83-
sourceInterval = new BlockProcessorSourceInterval( this );
8465
}
8566

8667
@Override
@@ -89,47 +70,9 @@ public BlockProcessor< I, O > independentCopy()
8970
return new ConvertBlockProcessor<>( this );
9071
}
9172

92-
@Override
93-
public void setTargetInterval( final Interval interval )
94-
{
95-
final int n = interval.numDimensions();
96-
if ( sourcePos == null || sourcePos.length != n )
97-
{
98-
sourcePos = new long[ n ];
99-
sourceSize = new int[ n ];
100-
}
101-
interval.min( sourcePos );
102-
Arrays.setAll( sourceSize, d -> safeInt( interval.dimension( d ) ) );
103-
sourceLength = safeInt( Intervals.numElements( sourceSize ) );
104-
}
105-
106-
@Override
107-
public long[] getSourcePos()
108-
{
109-
return sourcePos;
110-
}
111-
112-
@Override
113-
public int[] getSourceSize()
114-
{
115-
return sourceSize;
116-
}
117-
118-
@Override
119-
public Interval getSourceInterval()
120-
{
121-
return sourceInterval;
122-
}
123-
124-
@Override
125-
public I getSourceBuffer()
126-
{
127-
return tempArray.get( sourceLength );
128-
}
129-
13073
@Override
13174
public void compute( final I src, final O dest )
13275
{
133-
loop.apply( src, dest, sourceLength );
76+
loop.apply( src, dest, sourceLength() );
13477
}
13578
}

0 commit comments

Comments
 (0)