package com.testing;

import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;

public class H5TestFilter {

    public static void main(String args[]) throws Exception {

        System.out.println("starting...");
        System.out.println("...finished.");
        createFile("R:/test_without_filter.h5", false);
        createFile("R:/test_with_filter.h5", true);

    }

    public static void createFile(String fileName, boolean useFilter) throws Exception
    {
// create a new file
        int file_id = H5.H5Fcreate(fileName, HDF5Constants.H5F_ACC_TRUNC, HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);

// create a simple dataspace - size in zyx order
        int rank = 3;
        long[] shape = new long[]{20,512,512};
        int space_id = H5.H5Screate_simple(rank, shape, null);

// create "dataset creation property list" id (dcpl)
        int dcpl_id = H5.H5Pcreate(HDF5Constants.H5P_DATASET_CREATE);


// cd_values has all settings, and will be passed to the compression filter
        final int N_CD_VALUES = 7;
        int[] cd_values = new int[]{0, 101, 1000, 1000, 0, 0, 64};


// set chunked layout
        long[] chunkshape = new long[]{1,shape[1],shape[2]};
        int r = H5.H5Pset_chunk(dcpl_id, rank, chunkshape);

// set the filter
        if( useFilter )
        {
            int plugin_filter_id = 333;
            int avail = H5.H5Zfilter_avail(333);
            System.out.println("Filter 333 available: " + avail);
            int ok = H5.H5Pset_filter(dcpl_id, plugin_filter_id, HDF5Constants.H5Z_FLAG_MANDATORY, N_CD_VALUES, cd_values);
            System.out.println("Setting filter status: "+  ok);
        }

        long[] chunkshapeOut = new long[32];
        int dimensionsOut;
        H5.H5Pget_chunk(dcpl_id, 32, chunkshapeOut);


// create dataset
        String name = "data";
        int type_id = HDF5Constants.H5T_NATIVE_UINT16;
        int dataset_id;

        dataset_id = H5.H5Dcreate(file_id, name, type_id, space_id, 0, dcpl_id, 0);
        
// put stuff in data
        // ...
        int nx = (int)shape[2];
        int ny = (int)shape[1];
        int nz = (int)shape[0];

        short[] data = new short[ nz * ny * nx ];
        int i = 0;
        for (int x = 0; x < nx; x++)
            for (int y = 0; y < ny; y++)
                for (int z = 0; z < nz; z++)
                {
                    int pos = (int)(z * (shape[1]*shape[2]) + y * shape[1] + x);
                    data[ pos ] = (short) (x);
                }


// write the data
        H5.H5Dwrite(dataset_id,
                type_id,
                HDF5Constants.H5S_ALL,
                HDF5Constants.H5S_ALL,
                HDF5Constants.H5P_DEFAULT,
                data);

// close file
        H5.H5Fflush(file_id, HDF5Constants.H5F_SCOPE_GLOBAL);
        H5.H5Dclose(dataset_id);


    }
}
