1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /************************************************************
15  This example shows how to read and write data to a dataset
16  using the N-Bit filter.  The program first checks if the
17  N-Bit filter is available, then if it is it writes integers
18  to a dataset using N-Bit, then closes the file. Next, it
19  reopens the file, reads back the data, and outputs the type
20  of filter and the maximum value in the dataset to the screen.
21  ************************************************************/
22 
23 package examples.datasets;
24 
25 import java.util.EnumSet;
26 import java.util.HashMap;
27 import java.util.Map;
28 
29 import hdf.hdf5lib.H5;
30 import hdf.hdf5lib.HDF5Constants;
31 
32 public class H5Ex_D_Nbit {
33     private static String FILENAME = "H5Ex_D_Nbit.h5";
34     private static String DATASETNAME = "DS1";
35     private static final int DIM_X = 32;
36     private static final int DIM_Y = 64;
37     private static final int CHUNK_X = 4;
38     private static final int CHUNK_Y = 8;
39     private static final int RANK = 2;
40     private static final int NDIMS = 2;
41 
42     // Values for the status of space allocation
43     enum H5Z_filter {
44         H5Z_FILTER_ERROR(HDF5Constants.H5Z_FILTER_ERROR), H5Z_FILTER_NONE(HDF5Constants.H5Z_FILTER_NONE), H5Z_FILTER_DEFLATE(
45                 HDF5Constants.H5Z_FILTER_DEFLATE), H5Z_FILTER_SHUFFLE(HDF5Constants.H5Z_FILTER_SHUFFLE), H5Z_FILTER_FLETCHER32(
46                 HDF5Constants.H5Z_FILTER_FLETCHER32), H5Z_FILTER_SZIP(HDF5Constants.H5Z_FILTER_SZIP), H5Z_FILTER_NBIT(
47                 HDF5Constants.H5Z_FILTER_NBIT), H5Z_FILTER_SCALEOFFSET(HDF5Constants.H5Z_FILTER_SCALEOFFSET), H5Z_FILTER_RESERVED(
48                 HDF5Constants.H5Z_FILTER_RESERVED), H5Z_FILTER_MAX(HDF5Constants.H5Z_FILTER_MAX);
49         private static final Map<Integer, H5Z_filter> lookup = new HashMap<Integer, H5Z_filter>();
50 
51         static {
52             for (H5Z_filter s : EnumSet.allOf(H5Z_filter.class))
s.getCode()53                 lookup.put(s.getCode(), s);
54         }
55 
56         private int code;
57 
H5Z_filter(int layout_type)58         H5Z_filter(int layout_type) {
59             this.code = layout_type;
60         }
61 
getCode()62         public int getCode() {
63             return this.code;
64         }
65 
get(int code)66         public static H5Z_filter get(int code) {
67             return lookup.get(code);
68         }
69     }
70 
checkNbitFilter()71     private static boolean checkNbitFilter() {
72         try {
73             // Check if N-Bit compression is available and can be used for both compression and decompression.
74             int available = H5.H5Zfilter_avail(HDF5Constants.H5Z_FILTER_NBIT);
75             if (available == 0) {
76                 System.out.println("N-Bit filter not available.");
77                 return false;
78             }
79         }
80         catch (Exception e) {
81             e.printStackTrace();
82         }
83 
84         try {
85             int filter_info = H5.H5Zget_filter_info(HDF5Constants.H5Z_FILTER_NBIT);
86             if (((filter_info & HDF5Constants.H5Z_FILTER_CONFIG_ENCODE_ENABLED) == 0)
87                     || ((filter_info & HDF5Constants.H5Z_FILTER_CONFIG_DECODE_ENABLED) == 0)) {
88                 System.out.println("N-Bit filter not available for encoding and decoding.");
89                 return false;
90             }
91         }
92         catch (Exception e) {
93             e.printStackTrace();
94         }
95         return true;
96     }
97 
writeData()98     private static void writeData() throws Exception {
99         long file_id = -1;
100         long filespace_id = -1;
101         long dataset_id = -1;
102         long dtype_id = -1;
103         long dcpl_id = -1;
104         long[] dims = { DIM_X, DIM_Y };
105         long[] chunk_dims = { CHUNK_X, CHUNK_Y };
106         int[][] dset_data = new int[DIM_X][DIM_Y];
107 
108         // Initialize data.
109         for (int indx = 0; indx < DIM_X; indx++)
110             for (int jndx = 0; jndx < DIM_Y; jndx++)
111                 dset_data[indx][jndx] = indx * jndx - jndx;
112 
113         try {
114             // Create a new file using the default properties.
115             file_id = H5.H5Fcreate(FILENAME, HDF5Constants.H5F_ACC_TRUNC, HDF5Constants.H5P_DEFAULT,
116                     HDF5Constants.H5P_DEFAULT);
117 
118             // Create dataspace. Setting maximum size to NULL sets the maximum
119             // size to be the current size.
120             filespace_id = H5.H5Screate_simple(RANK, dims, null);
121 
122             // Create the datatype to use with the N-Bit filter. It has an uncompressed size of 32 bits,
123             // but will have a size of 16 bits after being packed by the N-Bit filter.
124             dtype_id = H5.H5Tcopy(HDF5Constants.H5T_STD_I32LE);
125             H5.H5Tset_precision(dtype_id, 16);
126             H5.H5Tset_offset(dtype_id, 5);
127 
128             // Create the dataset creation property list, add the N-Bit filter and set the chunk size.
129             dcpl_id = H5.H5Pcreate(HDF5Constants.H5P_DATASET_CREATE);
130             H5.H5Pset_nbit(dcpl_id);
131             H5.H5Pset_chunk(dcpl_id, NDIMS, chunk_dims);
132 
133             // Create the dataset.
134             dataset_id = H5.H5Dcreate(file_id, DATASETNAME, dtype_id, filespace_id, HDF5Constants.H5P_DEFAULT, dcpl_id,
135                     HDF5Constants.H5P_DEFAULT);
136 
137             // Write the data to the dataset.
138             H5.H5Dwrite(dataset_id, HDF5Constants.H5T_NATIVE_INT, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
139                     HDF5Constants.H5P_DEFAULT, dset_data);
140         }
141         catch (Exception e) {
142             e.printStackTrace();
143         }
144         finally {
145             // Close and release resources.
146             if (dcpl_id >= 0)
147                 H5.H5Pclose(dcpl_id);
148             if (dtype_id >= 0)
149                 H5.H5Tclose(dtype_id);
150             if (dataset_id >= 0)
151                 H5.H5Dclose(dataset_id);
152             if (filespace_id >= 0)
153                 H5.H5Sclose(filespace_id);
154             if (file_id >= 0)
155                 H5.H5Fclose(file_id);
156         }
157     }
158 
readData()159     private static void readData() throws Exception {
160         long file_id = -1;
161         long dataset_id = -1;
162         long dcpl_id = -1;
163         int[][] dset_data = new int[DIM_X][DIM_Y];
164 
165         // Open an existing file.
166         try {
167             file_id = H5.H5Fopen(FILENAME, HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT);
168         }
169         catch (Exception e) {
170             e.printStackTrace();
171         }
172 
173         // Open an existing dataset.
174         try {
175             if (file_id >= 0)
176                 dataset_id = H5.H5Dopen(file_id, DATASETNAME, HDF5Constants.H5P_DEFAULT);
177         }
178         catch (Exception e) {
179             e.printStackTrace();
180         }
181 
182         // Retrieve the dataset creation property list.
183         try {
184             if (dataset_id >= 0)
185                 dcpl_id = H5.H5Dget_create_plist(dataset_id);
186         }
187         catch (Exception e) {
188             e.printStackTrace();
189         }
190 
191         // Retrieve and print the filter type. Here we only retrieve the
192         // first filter because we know that we only added one filter.
193         try {
194             if (dcpl_id >= 0) {
195                 // Java lib requires a valid filter_name object and cd_values
196                 int[] flags = { 0 };
197                 long[] cd_nelmts = { 1 };
198                 int[] cd_values = { 0 };
199                 String[] filter_name = { "" };
200                 int[] filter_config = { 0 };
201                 int filter_type = -1;
202                 filter_type = H5
203                         .H5Pget_filter(dcpl_id, 0, flags, cd_nelmts, cd_values, 120, filter_name, filter_config);
204                 System.out.print("Filter type is: ");
205                 switch (H5Z_filter.get(filter_type)) {
206                 case H5Z_FILTER_DEFLATE:
207                     System.out.println("H5Z_FILTER_DEFLATE");
208                     break;
209                 case H5Z_FILTER_SHUFFLE:
210                     System.out.println("H5Z_FILTER_SHUFFLE");
211                     break;
212                 case H5Z_FILTER_FLETCHER32:
213                     System.out.println("H5Z_FILTER_FLETCHER32");
214                     break;
215                 case H5Z_FILTER_SZIP:
216                     System.out.println("H5Z_FILTER_SZIP");
217                     break;
218                 case H5Z_FILTER_NBIT:
219                     System.out.println("H5Z_FILTER_NBIT");
220                     break;
221                 case H5Z_FILTER_SCALEOFFSET:
222                     System.out.println("H5Z_FILTER_SCALEOFFSET");
223                     break;
224                 default:
225                     System.out.println("H5Z_FILTER_ERROR");
226                 }
227                 System.out.println();
228             }
229         }
230         catch (Exception e) {
231             e.printStackTrace();
232         }
233 
234         // Read the data using the default properties.
235         try {
236             if (dataset_id >= 0) {
237                 int status = H5.H5Dread(dataset_id, HDF5Constants.H5T_NATIVE_INT, HDF5Constants.H5S_ALL,
238                         HDF5Constants.H5S_ALL, HDF5Constants.H5P_DEFAULT, dset_data);
239                 // Check if the read was successful.
240                 if (status < 0)
241                     System.out.print("Dataset read failed!");
242             }
243         }
244         catch (Exception e) {
245             e.printStackTrace();
246         }
247 
248         // Find the maximum value in the dataset, to verify that it was read
249         // correctly.
250         int max = dset_data[0][0];
251         for (int indx = 0; indx < DIM_X; indx++) {
252             for (int jndx = 0; jndx < DIM_Y; jndx++)
253                 if (max < dset_data[indx][jndx])
254                     max = dset_data[indx][jndx];
255         }
256         // Print the maximum value.
257         System.out.println("Maximum value in " + DATASETNAME + " is: " + max);
258 
259         // End access to the dataset and release resources used by it.
260         try {
261             if (dcpl_id >= 0)
262                 H5.H5Pclose(dcpl_id);
263         }
264         catch (Exception e) {
265             e.printStackTrace();
266         }
267 
268         try {
269             if (dataset_id >= 0)
270                 H5.H5Dclose(dataset_id);
271         }
272         catch (Exception e) {
273             e.printStackTrace();
274         }
275 
276         // Close the file.
277         try {
278             if (file_id >= 0)
279                 H5.H5Fclose(file_id);
280         }
281         catch (Exception e) {
282             e.printStackTrace();
283         }
284 
285     }
286 
main(String[] args)287     public static void main(String[] args) {
288         /*
289          * Check if N-Bit compression is available and can be used for both compression and decompression. Normally we
290          * do not perform error checking in these examples for the sake of clarity, but in this case we will make an
291          * exception because this filter is an optional part of the hdf5 library.
292          */
293         try {
294             if (H5Ex_D_Nbit.checkNbitFilter()) {
295                 H5Ex_D_Nbit.writeData();
296                 H5Ex_D_Nbit.readData();
297             }
298         }
299         catch (Exception ex) {
300             ex.printStackTrace();
301         }
302     }
303 }
304