3131import com .google .gson .JsonDeserializationContext ;
3232import com .google .gson .JsonDeserializer ;
3333import com .google .gson .JsonElement ;
34+ import com .google .gson .JsonNull ;
3435import com .google .gson .JsonObject ;
3536import com .google .gson .JsonParseException ;
3637import com .google .gson .JsonSerializationContext ;
5253import java .util .stream .Collectors ;
5354
5455import org .janelia .saalfeldlab .n5 .codec .DataCodecInfo ;
56+ import org .janelia .saalfeldlab .n5 .codec .DatasetCodec ;
57+ import org .janelia .saalfeldlab .n5 .codec .DatasetCodecInfo ;
5558
5659
5760/**
@@ -95,23 +98,30 @@ public class DatasetAttributes implements Serializable {
9598
9699 private final DataType dataType ;
97100
101+ private final JsonElement defaultValue ;
102+
98103 private final BlockCodecInfo blockCodecInfo ;
99104 private final DataCodecInfo [] dataCodecInfos ;
105+ private final DatasetCodecInfo [] datasetCodecInfos ;
100106
101107 private transient final DatasetAccess <?> access ;
102108
103109 public DatasetAttributes (
104110 final long [] dimensions ,
105111 final int [] outerBlockSize ,
106112 final DataType dataType ,
113+ final JsonElement defaultValue ,
107114 final BlockCodecInfo blockCodecInfo ,
115+ final DatasetCodecInfo [] datasetCodecInfos ,
108116 final DataCodecInfo ... dataCodecInfos ) {
109117
110118 this .dimensions = dimensions ;
111119 this .dataType = dataType ;
112120 this .outerBlockSize = outerBlockSize ;
121+ this .defaultValue = defaultValue == null ? JsonNull .INSTANCE : defaultValue ;
113122
114123 this .blockCodecInfo = blockCodecInfo == null ? defaultBlockCodecInfo () : blockCodecInfo ;
124+ this .datasetCodecInfos = datasetCodecInfos ;
115125
116126 if (dataCodecInfos == null )
117127 this .dataCodecInfos = new DataCodecInfo [0 ];
@@ -124,6 +134,28 @@ public DatasetAttributes(
124134 blockSize = access .getGrid ().getBlockSize (0 );
125135 }
126136
137+ public DatasetAttributes (
138+ final long [] dimensions ,
139+ final int [] outerBlockSize ,
140+ final DataType dataType ,
141+ final BlockCodecInfo blockCodecInfo ,
142+ final DatasetCodecInfo [] datasetCodecInfos ,
143+ final DataCodecInfo ... dataCodecInfos ) {
144+
145+ this (dimensions , outerBlockSize , dataType , JsonNull .INSTANCE ,
146+ blockCodecInfo , datasetCodecInfos , dataCodecInfos );
147+ }
148+
149+ public DatasetAttributes (
150+ final long [] dimensions ,
151+ final int [] outerBlockSize ,
152+ final DataType dataType ,
153+ final BlockCodecInfo blockCodecInfo ,
154+ final DataCodecInfo ... dataCodecInfos ) {
155+
156+ this (dimensions , outerBlockSize , dataType , blockCodecInfo , null , dataCodecInfos );
157+ }
158+
127159 /**
128160 * Constructs a DatasetAttributes instance with specified dimensions, block size, data type,
129161 * and single compressor with default codec.
@@ -165,7 +197,7 @@ protected DatasetAccess<?> createDatasetAccess() {
165197 // The inner-most codec (the DataBlock codec) is at index 0.
166198 final int [][] blockSizes = new int [m ][];
167199
168- // NestedGrid validates block sizes, so instantiate it before creating the blockCodecs
200+ // NestedGrid validates block sizes, so instantiate it before creating the blockCodecs
169201 // blockCodecInfo.create below could fail unexpecedly with invalid
170202 // blockSizes so validate first
171203 blockSizes [m - 1 ] = outerBlockSize ;
@@ -179,17 +211,23 @@ protected DatasetAccess<?> createDatasetAccess() {
179211 BlockCodecInfo currentBlockCodecInfo = blockCodecInfo ;
180212 DataCodecInfo [] currentDataCodecInfos = dataCodecInfos ;
181213
182- final NestedGrid grid = new NestedGrid (blockSizes );
214+ final NestedGrid grid = new NestedGrid (blockSizes , dimensions );
183215 final BlockCodec <?>[] blockCodecs = new BlockCodec [m ];
184216 for (int l = m - 1 ; l >= 0 ; --l ) {
185217 blockCodecs [l ] = currentBlockCodecInfo .create (dataType , blockSizes [l ], currentDataCodecInfos );
186218 if (l > 0 ) {
187- final ShardCodecInfo info = (ShardCodecInfo )currentBlockCodecInfo ;
219+ final ShardCodecInfo info = (ShardCodecInfo ) currentBlockCodecInfo ;
188220 currentBlockCodecInfo = info .getInnerBlockCodecInfo ();
189221 currentDataCodecInfos = info .getInnerDataCodecInfos ();
190222 }
191223 }
192224
225+ if (datasetCodecInfos != null ) {
226+ for (final DatasetCodecInfo info : datasetCodecInfos ) {
227+ blockCodecs [0 ] = DatasetCodec .concatenate (info .create (this ), (BlockCodec ) blockCodecs [0 ]);
228+ }
229+ }
230+
193231 return new DefaultDatasetAccess <>(grid , blockCodecs );
194232 }
195233
@@ -202,7 +240,6 @@ private static int nestingDepth(BlockCodecInfo info) {
202240 }
203241 }
204242
205-
206243 protected BlockCodecInfo defaultBlockCodecInfo () {
207244
208245 return new N5BlockCodecInfo ();
@@ -223,6 +260,11 @@ public int[] getBlockSize() {
223260 return blockSize ;
224261 }
225262
263+ public JsonElement getDefaultValue () {
264+
265+ return defaultValue ;
266+ }
267+
226268 public boolean isSharded () {
227269
228270 return blockCodecInfo instanceof ShardCodecInfo ;
@@ -284,6 +326,11 @@ public DataCodecInfo[] getDataCodecInfos() {
284326 return dataCodecInfos ;
285327 }
286328
329+ public DatasetCodecInfo [] getDatasetCodecInfos () {
330+
331+ return datasetCodecInfos ;
332+ }
333+
287334 public String relativeBlockPath (long ... position ) {
288335
289336 return Arrays .stream (position ).mapToObj (Long ::toString ).collect (Collectors .joining ("/" ));
0 commit comments