Skip to content

Commit 6b36b52

Browse files
authored
Merge pull request #1561 from lesserwhirls/gh-1556
Extend limited reader in H5headerNew to handle filtered data
2 parents cd207a9 + 3b5eff7 commit 6b36b52

2 files changed

Lines changed: 59 additions & 6 deletions

File tree

cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5headerNew.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
2+
* Copyright (c) 1998-2026 University Corporation for Atmospheric Research/Unidata
33
* See LICENSE for license information.
44
*/
55

@@ -25,6 +25,7 @@
2525
import ucar.ma2.ArrayStructure;
2626
import ucar.ma2.ArrayStructureBB;
2727
import ucar.ma2.DataType;
28+
import ucar.ma2.Index;
2829
import ucar.ma2.IndexIterator;
2930
import ucar.ma2.InvalidRangeException;
3031
import ucar.ma2.Section;
@@ -59,6 +60,7 @@
5960
import ucar.nc2.write.NetcdfFileFormat;
6061
import ucar.nc2.iosp.IospHelper;
6162
import ucar.nc2.iosp.Layout;
63+
import ucar.nc2.iosp.LayoutBB;
6264
import ucar.nc2.iosp.LayoutRegular;
6365
import ucar.nc2.iosp.hdf5.DataBTree;
6466
import ucar.nc2.iosp.hdf5.H5headerIF;
@@ -1957,6 +1959,29 @@ Object getFillValueNonDefault() {
19571959
Array readArray() throws IOException {
19581960
int[] shape = mds.dimLength;
19591961
DataType dataType = typeInfo.dataType;
1962+
1963+
if (useFillValue) {
1964+
Object pa = IospHelper.makePrimitiveArray((int) Index.computeSize(shape), dataType, getFillValue());
1965+
if (dataType == DataType.CHAR)
1966+
pa = IospHelper.convertByteToChar((byte[]) pa);
1967+
return Array.factory(dataType, shape, pa);
1968+
}
1969+
1970+
// filtered, must read and decode by chunk
1971+
if (mfp != null) {
1972+
ByteOrder bo = (typeInfo.endian == 0) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
1973+
LayoutBB layoutBB;
1974+
try {
1975+
layoutBB = new H5tiledLayoutBB(this, shape, dataType.getSize(), new Section(shape), getRandomAccessFile(),
1976+
mfp.getFilters(), bo);
1977+
} catch (InvalidRangeException e) {
1978+
// should not happen because we passed in the full shape
1979+
throw new IllegalStateException();
1980+
}
1981+
Object data = IospHelper.readDataFill(layoutBB, dataType, getFillValue());
1982+
return Array.factory(dataType, shape, data);
1983+
}
1984+
19601985
Layout layout;
19611986
try {
19621987
if (isChunked) {
@@ -1977,6 +2002,15 @@ Array readArray() throws IOException {
19772002
String readString() throws IOException {
19782003
int[] shape = new int[] {mdt.byteSize};
19792004
DataType dataType = typeInfo.dataType;
2005+
2006+
if (useFillValue) {
2007+
Object pa = IospHelper.makePrimitiveArray((int) Index.computeSize(shape), dataType, getFillValue());
2008+
if (dataType == DataType.CHAR)
2009+
pa = IospHelper.convertByteToChar((byte[]) pa);
2010+
Array dataArray = Array.factory(dataType, shape, pa);
2011+
return (dataArray instanceof ArrayChar.D1) ? ((ArrayChar) dataArray).getString() : "";
2012+
}
2013+
19802014
Layout layout;
19812015
try {
19822016
if (isChunked) {

cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5tiledLayoutBB.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/*
2-
* Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
2+
* Copyright (c) 1998-2026 John Caron and University Corporation for Atmospheric Research/Unidata
33
* See LICENSE for license information.
44
*/
5+
56
package ucar.nc2.internal.iosp.hdf5;
67

78
import com.google.common.primitives.Ints;
@@ -71,9 +72,27 @@ public class H5tiledLayoutBB implements LayoutBB {
7172
*/
7273
public H5tiledLayoutBB(Variable v2, Section wantSection, RandomAccessFile raf, H5objects.Filter[] filterProps,
7374
ByteOrder byteOrder) throws InvalidRangeException, IOException {
74-
wantSection = Section.fill(wantSection, v2.getShape());
75+
this((H5headerNew.Vinfo) v2.getSPobject(), v2.getShape(), v2.getElementSize(), wantSection, raf, filterProps,
76+
byteOrder);
77+
}
78+
79+
/**
80+
* This constructor can be used when the Variable is not yet built.
81+
*
82+
* @param vinfo the data object
83+
* @param varShape the variable's shape
84+
* @param elemSize the variable's element size in bytes
85+
* @param wantSection the wanted section of data, contains a List of Range objects. must be complete
86+
* @param raf the RandomAccessFile
87+
* @param filterProps set of filter properties from which filter object will be created
88+
* @throws InvalidRangeException if section invalid for this variable
89+
* @throws IOException on io error
90+
*/
91+
H5tiledLayoutBB(H5headerNew.Vinfo vinfo, int[] varShape, int elemSize, Section wantSection, RandomAccessFile raf,
92+
H5objects.Filter[] filterProps, ByteOrder byteOrder) throws InvalidRangeException, IOException {
93+
94+
wantSection = Section.fill(wantSection, varShape);
7595

76-
H5headerNew.Vinfo vinfo = (H5headerNew.Vinfo) v2.getSPobject();
7796
assert vinfo.isChunked;
7897
assert vinfo.btree != null;
7998

@@ -82,7 +101,7 @@ public H5tiledLayoutBB(Variable v2, Section wantSection, RandomAccessFile raf, H
82101
for (int i = 0; i < filterProps.length; i++) {
83102
// add var info to filter props
84103
Map<String, Object> props = filterProps[i].getProperties();
85-
props.put(Filters.Keys.ELEM_SIZE, v2.getElementSize());
104+
props.put(Filters.Keys.ELEM_SIZE, elemSize);
86105
// try to get filter by name or id, throw if not recognized filter
87106
try {
88107
filters[i] = Filters.getFilter(props);
@@ -95,7 +114,7 @@ public H5tiledLayoutBB(Variable v2, Section wantSection, RandomAccessFile raf, H
95114
// we have to translate the want section into the same rank as the storageSize, in order to be able to call
96115
// Section.intersect(). It appears that storageSize (actually msl.chunkSize) may have an extra dimension, relative
97116
// to the Variable.
98-
DataType dtype = v2.getDataType();
117+
DataType dtype = vinfo.getNCDataType();
99118
if ((dtype == DataType.CHAR) && (wantSection.getRank() < vinfo.storageSize.length)) {
100119
this.want = Section.builder().appendRanges(wantSection.getRanges()).appendRange(1).build();
101120
} else {

0 commit comments

Comments
 (0)