public int read(byte[] b) throws IOException {
        // empty the buffer before reading more data
        if (buffer != null) {
            int amount = (buffer.length - pos) <= b.length ? buffer.length - pos : b.length;
            System.arraycopy(buffer, pos, b, 0, amount);
            if (pos + amount < buffer.length) {
                pos += amount;
            } else {
                buffer = null;
                pos = 0;
            }
            return amount;
        }

        // now we are sure the buffer is empty and read on
        int n = source.read(b);
        if (n > 0) {
            byte[] tmp = new byte[n];
            System.arraycopy(b, 0, tmp, 0, n);
            buffer = transpose(tmp);
            if (buffer != null && buffer.length > 0) {
                int amount = buffer.length <= b.length ? buffer.length : b.length;
                System.arraycopy(buffer, 0, b, 0, amount);
                pos = n = amount;
                if (amount == buffer.length) {
                    buffer = null;
                    pos = 0;
                }
            } else {
                return 0;
            }
        }
        return n;
    }