public float[] calculate(float[] x) {
        // length of output array
        int n = range.length / 2;
        // ready output array
        float y[] = new float[n];
        // work throw all input data and store in y[]
        try {
            for (int i = 0; i < x.length; i++) {
                // clip input value appropriately for the given domain
                // xi' = min (max(xi, Domain2i), Domain2i+1)
                x[i] = Math.min(Math.max(x[i], domain[2 * i]), domain[2 * i + 1]);
                // find the encoded value
                // ei = intermolate (xi', Domain2i, Domain2i+1, Encode2i, Encode2i+1)
                float e = interpolate(x[i], domain[2 * i], domain[2 * i + 1],
                        encode[2 * i], encode[2 * i + 1]);
                // clip to the size of the sampled table in that dimension:
                // ei' = min (max(ei, 0), Sizei-1)
                e = Math.min(Math.max(e, 0), size[i] - 1);
                // pretty sure that e1 and e2 are used to for a bilinear interpolation?
                // Output values are are caculated from the nearest surrounding values
                // in the sample table in the sample table.
                int e1 = (int) Math.floor(e);
                int e2 = (int) Math.ceil(e);
                int index;
                // Calculate the final output values
                for (int j = 0; j < n; j++) {
                    //  find nearest surrounding values in the sample table
                    int b1 = ((int) bytes[(int) (e1 * n + j)]) & 255;
                    int b2 = ((int) bytes[(int) (e2 * n + j)]) & 255;
                    // get the average
                    float r = ((float) b1 + (float) b2) / 2;
                    // interplate to get output values
                    r = interpolate(r, 0f, (float) Math.pow(2, bitspersample) -
                            1, decode[2 * j], decode[2 * j + 1]);
                    // finally, decoded values are clipped ot the range
                    // yj = min(max(rj', Range2j), Range2j+1)
                    r = Math.min(Math.max(r, range[2 * j]), range[2 * j + 1]);
                    index = i * n + j;
                    // make sure we y can contain the calcualated r value
                    if (index < y.length) {
                        y[index] = r;
                    }

                }
            }
        }
        catch (Exception e) {
            logger.log(Level.WARNING, "Error calculating function 0 values", e);
        }
        return y;
    }