You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by al...@apache.org on 2023/02/10 03:08:47 UTC

[datasketches-java] 01/01: theta compression

This is an automated email from the ASF dual-hosted git repository.

alsay pushed a commit to branch theta_compression
in repository https://gitbox.apache.org/repos/asf/datasketches-java.git

commit 66375090f1cd5085c14f8b0530d7b3821291d5b1
Author: AlexanderSaydakov <Al...@users.noreply.github.com>
AuthorDate: Thu Feb 9 19:08:37 2023 -0800

    theta compression
---
 .../org/apache/datasketches/theta/BitPacking.java  | 6271 ++++++++++++++++++++
 .../apache/datasketches/theta/CompactSketch.java   |  244 +-
 .../apache/datasketches/theta/PreambleUtil.java    |   17 +
 .../org/apache/datasketches/theta/UnionImpl.java   |   14 +-
 .../apache/datasketches/theta/BitPackingTest.java  |   99 +
 .../datasketches/theta/CompactSketchTest.java      |   34 +
 .../apache/datasketches/theta/UnionImplTest.java   |   17 +
 7 files changed, 6614 insertions(+), 82 deletions(-)

diff --git a/src/main/java/org/apache/datasketches/theta/BitPacking.java b/src/main/java/org/apache/datasketches/theta/BitPacking.java
new file mode 100644
index 00000000..7776a667
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/theta/BitPacking.java
@@ -0,0 +1,6271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.theta;
+
+import org.apache.datasketches.common.SketchesArgumentException;
+
+public class BitPacking {
+
+  public static void packBits(long value, int bits, byte[] buffer, int bufOffset, int bitOffset) {
+    if (bitOffset > 0) {
+      final int chunkBits = 8 - bitOffset;
+      final int mask = (1 << chunkBits) - 1;
+      if (bits < chunkBits) {
+        buffer[bufOffset] |= (value << (chunkBits - bits)) & mask;
+        return;
+      }
+      buffer[bufOffset++] |= (value >>> (bits - chunkBits)) & mask;
+      bits -= chunkBits;
+    }
+    while (bits >= 8) {
+      buffer[bufOffset++] = (byte)(value >>> (bits - 8));
+      bits -= 8;
+    }
+    if (bits > 0) {
+      buffer[bufOffset] = (byte)(value << (8 - bits));
+    }
+  }
+
+  public static void unpackBits(long[] value, int index, int bits, byte[] buffer, int bufOffset, int bitOffset) {
+    final int availBits = 8 - bitOffset;
+    final int chunkBits = availBits <= bits ? availBits : bits;
+    final int mask = (1 << chunkBits) - 1;
+    value[index] = (buffer[bufOffset] >>> (availBits - chunkBits)) & mask;
+    bufOffset += availBits == chunkBits ? 1 : 0;
+    bits -= chunkBits;
+    while (bits >= 8) {
+      value[index] <<= 8;
+      value[index] |= (Byte.toUnsignedLong(buffer[bufOffset++]));
+      bits -= 8;
+    }
+    if (bits > 0) {
+      value[index] <<= bits;
+      value[index] |= Byte.toUnsignedLong(buffer[bufOffset]) >>> (8 - bits);
+    }
+  }
+
+  // pack given number of bits from a block of 8 64-bit values into bytes
+  // we don't need 0 and 64 bits
+  // we assume that higher bits (which we are not packing) are zeros
+  // this assumption allows to avoid masking operations
+
+  static void packBitsBlock8(long[] values, int i, byte[] buf, int off, int bits) {
+    switch (bits) {
+      case 1: packBits1(values, i, buf, off); break;
+      case 2: packBits2(values, i, buf, off); break;
+      case 3: packBits3(values, i, buf, off); break;
+      case 4: packBits4(values, i, buf, off); break;
+      case 5: packBits5(values, i, buf, off); break;
+      case 6: packBits6(values, i, buf, off); break;
+      case 7: packBits7(values, i, buf, off); break;
+      case 8: packBits8(values, i, buf, off); break;
+      case 9: packBits9(values, i, buf, off); break;
+      case 10: packBits10(values, i, buf, off); break;
+      case 11: packBits11(values, i, buf, off); break;
+      case 12: packBits12(values, i, buf, off); break;
+      case 13: packBits13(values, i, buf, off); break;
+      case 14: packBits14(values, i, buf, off); break;
+      case 15: packBits15(values, i, buf, off); break;
+      case 16: packBits16(values, i, buf, off); break;
+      case 17: packBits17(values, i, buf, off); break;
+      case 18: packBits18(values, i, buf, off); break;
+      case 19: packBits19(values, i, buf, off); break;
+      case 20: packBits20(values, i, buf, off); break;
+      case 21: packBits21(values, i, buf, off); break;
+      case 22: packBits22(values, i, buf, off); break;
+      case 23: packBits23(values, i, buf, off); break;
+      case 24: packBits24(values, i, buf, off); break;
+      case 25: packBits25(values, i, buf, off); break;
+      case 26: packBits26(values, i, buf, off); break;
+      case 27: packBits27(values, i, buf, off); break;
+      case 28: packBits28(values, i, buf, off); break;
+      case 29: packBits29(values, i, buf, off); break;
+      case 30: packBits30(values, i, buf, off); break;
+      case 31: packBits31(values, i, buf, off); break;
+      case 32: packBits32(values, i, buf, off); break;
+      case 33: packBits33(values, i, buf, off); break;
+      case 34: packBits34(values, i, buf, off); break;
+      case 35: packBits35(values, i, buf, off); break;
+      case 36: packBits36(values, i, buf, off); break;
+      case 37: packBits37(values, i, buf, off); break;
+      case 38: packBits38(values, i, buf, off); break;
+      case 39: packBits39(values, i, buf, off); break;
+      case 40: packBits40(values, i, buf, off); break;
+      case 41: packBits41(values, i, buf, off); break;
+      case 42: packBits42(values, i, buf, off); break;
+      case 43: packBits43(values, i, buf, off); break;
+      case 44: packBits44(values, i, buf, off); break;
+      case 45: packBits45(values, i, buf, off); break;
+      case 46: packBits46(values, i, buf, off); break;
+      case 47: packBits47(values, i, buf, off); break;
+      case 48: packBits48(values, i, buf, off); break;
+      case 49: packBits49(values, i, buf, off); break;
+      case 50: packBits50(values, i, buf, off); break;
+      case 51: packBits51(values, i, buf, off); break;
+      case 52: packBits52(values, i, buf, off); break;
+      case 53: packBits53(values, i, buf, off); break;
+      case 54: packBits54(values, i, buf, off); break;
+      case 55: packBits55(values, i, buf, off); break;
+      case 56: packBits56(values, i, buf, off); break;
+      case 57: packBits57(values, i, buf, off); break;
+      case 58: packBits58(values, i, buf, off); break;
+      case 59: packBits59(values, i, buf, off); break;
+      case 60: packBits60(values, i, buf, off); break;
+      case 61: packBits61(values, i, buf, off); break;
+      case 62: packBits62(values, i, buf, off); break;
+      case 63: packBits63(values, i, buf, off); break;
+      default: throw new SketchesArgumentException("wrong number of bits " + bits);
+    }
+  }
+
+  static void unpackBitsBlock8(long[] values, int i, byte[] buf, int off, int bits) {
+    switch (bits) {
+      case 1: unpackBits1(values, i, buf, off); break;
+      case 2: unpackBits2(values, i, buf, off); break;
+      case 3: unpackBits3(values, i, buf, off); break;
+      case 4: unpackBits4(values, i, buf, off); break;
+      case 5: unpackBits5(values, i, buf, off); break;
+      case 6: unpackBits6(values, i, buf, off); break;
+      case 7: unpackBits7(values, i, buf, off); break;
+      case 8: unpackBits8(values, i, buf, off); break;
+      case 9: unpackBits9(values, i, buf, off); break;
+      case 10: unpackBits10(values, i, buf, off); break;
+      case 11: unpackBits11(values, i, buf, off); break;
+      case 12: unpackBits12(values, i, buf, off); break;
+      case 13: unpackBits13(values, i, buf, off); break;
+      case 14: unpackBits14(values, i, buf, off); break;
+      case 15: unpackBits15(values, i, buf, off); break;
+      case 16: unpackBits16(values, i, buf, off); break;
+      case 17: unpackBits17(values, i, buf, off); break;
+      case 18: unpackBits18(values, i, buf, off); break;
+      case 19: unpackBits19(values, i, buf, off); break;
+      case 20: unpackBits20(values, i, buf, off); break;
+      case 21: unpackBits21(values, i, buf, off); break;
+      case 22: unpackBits22(values, i, buf, off); break;
+      case 23: unpackBits23(values, i, buf, off); break;
+      case 24: unpackBits24(values, i, buf, off); break;
+      case 25: unpackBits25(values, i, buf, off); break;
+      case 26: unpackBits26(values, i, buf, off); break;
+      case 27: unpackBits27(values, i, buf, off); break;
+      case 28: unpackBits28(values, i, buf, off); break;
+      case 29: unpackBits29(values, i, buf, off); break;
+      case 30: unpackBits30(values, i, buf, off); break;
+      case 31: unpackBits31(values, i, buf, off); break;
+      case 32: unpackBits32(values, i, buf, off); break;
+      case 33: unpackBits33(values, i, buf, off); break;
+      case 34: unpackBits34(values, i, buf, off); break;
+      case 35: unpackBits35(values, i, buf, off); break;
+      case 36: unpackBits36(values, i, buf, off); break;
+      case 37: unpackBits37(values, i, buf, off); break;
+      case 38: unpackBits38(values, i, buf, off); break;
+      case 39: unpackBits39(values, i, buf, off); break;
+      case 40: unpackBits40(values, i, buf, off); break;
+      case 41: unpackBits41(values, i, buf, off); break;
+      case 42: unpackBits42(values, i, buf, off); break;
+      case 43: unpackBits43(values, i, buf, off); break;
+      case 44: unpackBits44(values, i, buf, off); break;
+      case 45: unpackBits45(values, i, buf, off); break;
+      case 46: unpackBits46(values, i, buf, off); break;
+      case 47: unpackBits47(values, i, buf, off); break;
+      case 48: unpackBits48(values, i, buf, off); break;
+      case 49: unpackBits49(values, i, buf, off); break;
+      case 50: unpackBits50(values, i, buf, off); break;
+      case 51: unpackBits51(values, i, buf, off); break;
+      case 52: unpackBits52(values, i, buf, off); break;
+      case 53: unpackBits53(values, i, buf, off); break;
+      case 54: unpackBits54(values, i, buf, off); break;
+      case 55: unpackBits55(values, i, buf, off); break;
+      case 56: unpackBits56(values, i, buf, off); break;
+      case 57: unpackBits57(values, i, buf, off); break;
+      case 58: unpackBits58(values, i, buf, off); break;
+      case 59: unpackBits59(values, i, buf, off); break;
+      case 60: unpackBits60(values, i, buf, off); break;
+      case 61: unpackBits61(values, i, buf, off); break;
+      case 62: unpackBits62(values, i, buf, off); break;
+      case 63: unpackBits63(values, i, buf, off); break;
+      default: throw new SketchesArgumentException("wrong number of bits " + bits);
+    }
+  }
+
+  static void packBits1(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[i + 0] << 7);
+    buf[off] |= values[i + 1] << 6;
+    buf[off] |= values[i + 2] << 5;
+    buf[off] |= values[i + 3] << 4;
+    buf[off] |= values[i + 4] << 3;
+    buf[off] |= values[i + 5] << 2;
+    buf[off] |= values[i + 6] << 1;
+    buf[off] |= values[i + 7];
+  }
+
+  static void packBits2(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[0] << 6);
+    buf[off] |= values[1] << 4;
+    buf[off] |= values[2] << 2;
+    buf[off++] |= values[3];
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off] |= values[5] << 4;
+    buf[off] |= values[6] << 2;
+    buf[off] |= values[7];
+  }
+
+  static void packBits3(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[0] << 5);
+    buf[off] |= values[1] << 2;
+    buf[off++] |= values[2] >>> 1;
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off] |= values[3] << 4;
+    buf[off] |= values[4] << 1;
+    buf[off++] |= values[5] >>> 2;
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off] |= values[6] << 3;
+    buf[off] |= values[7];
+  }
+
+  static void packBits4(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1];
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3];
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5];
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off] |= values[7];
+  }
+
+  static void packBits5(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 2;
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off] |= values[2] << 1;
+    buf[off++] |= values[3] >>> 4;
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 1;
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off] |= values[5] << 2;
+    buf[off++] |= values[6] >>> 3;
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off] |= values[7];
+  }
+
+  static void packBits6(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 4;
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 2;
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3];
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 4;
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 2;
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off] |= values[7];
+  }
+
+  static void packBits7(long[] values, int i, byte[] buf, int off) {
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 6;
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 5;
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 4;
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 3;
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 2;
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 1;
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off] |= values[7];
+  }
+
+  static void packBits8(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0]);
+    buf[off++] = (byte) (values[1]);
+    buf[off++] = (byte) (values[2]);
+    buf[off++] = (byte) (values[3]);
+    buf[off++] = (byte) (values[4]);
+    buf[off++] = (byte) (values[5]);
+    buf[off++] = (byte) (values[6]);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits9(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 2;
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 3;
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 4;
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 5;
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 6;
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 7;
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits10(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 4;
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 6;
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 8;
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 4;
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 6;
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits11(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 6;
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 9;
+
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 4;
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 7;
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 10;
+
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 5;
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits12(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 4);
+
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 8;
+
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 4);
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 8;
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 4);
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 8;
+
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 4);
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits13(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 10;
+
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 7;
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 12;
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] >>> 4);
+    buf[off++] |= values[4] >>> 9;
+
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 6;
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 11;
+
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits14(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 12;
+
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 10;
+
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 8;
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 12;
+
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 10;
+
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits15(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 14;
+
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 13;
+
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 12;
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 11;
+
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 10;
+
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 9;
+
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 8;
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits16(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 8);
+    buf[off++] = (byte) (values[0]);
+
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 8);
+    buf[off++] = (byte) (values[2]);
+
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 8);
+    buf[off++] = (byte) (values[4]);
+
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 8);
+    buf[off++] = (byte) (values[6]);
+
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits17(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 9);
+
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 10;
+
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 11;
+
+    buf[off++] = (byte) (values[2] >>> 3);
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 12;
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 13;
+
+    buf[off++] = (byte) (values[4] >>> 5);
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 14;
+
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 15;
+
+    buf[off++] = (byte) (values[6] >>> 7);
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits18(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 10);
+
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 12;
+
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 14;
+
+    buf[off++] = (byte) (values[2] >>> 6);
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 16;
+
+    buf[off++] = (byte) (values[3] >>> 8);
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 10);
+
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 12;
+
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 14;
+
+    buf[off++] = (byte) (values[6] >>> 6);
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits19(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 11);
+
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 14;
+
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 17;
+
+    buf[off++] = (byte) (values[2] >>> 9);
+
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 12;
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 15;
+
+    buf[off++] |= values[4] >>> 7;
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 18;
+
+    buf[off++] = (byte) (values[5] >>> 10);
+
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 13;
+
+    buf[off++] = (byte) (values[6] >>> 5);
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits20(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 12);
+
+    buf[off++] = (byte) (values[0] >>> 4);
+
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 16;
+
+    buf[off++] = (byte) (values[1] >>> 8);
+
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 12);
+
+    buf[off++] = (byte) (values[2] >>> 4);
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 16;
+
+    buf[off++] = (byte) (values[3] >>> 8);
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 12);
+
+    buf[off++] = (byte) (values[4] >>> 4);
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 16;
+
+    buf[off++] = (byte) (values[5] >>> 8);
+
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 12);
+
+    buf[off++] = (byte) (values[6] >>> 4);
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits21(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 13);
+
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 18;
+
+    buf[off++] = (byte) (values[1] >>> 10);
+
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 15;
+
+    buf[off++] = (byte) (values[2] >>> 7);
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 20;
+
+    buf[off++] = (byte) (values[3] >>> 12);
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 17;
+
+    buf[off++] = (byte) (values[4] >>> 9);
+
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 14;
+
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 19;
+
+    buf[off++] = (byte) (values[6] >>> 11);
+
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits22(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 14);
+
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 20;
+
+    buf[off++] = (byte) (values[1] >>> 12);
+
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 18;
+
+    buf[off++] = (byte) (values[2] >>> 10);
+
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 16;
+
+    buf[off++] = (byte) (values[3] >>> 8);
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 14);
+
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 20;
+
+    buf[off++] = (byte) (values[5] >>> 12);
+
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 18;
+
+    buf[off++] = (byte) (values[6] >>> 10);
+
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits23(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 15);
+
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 22;
+
+    buf[off++] = (byte) (values[1] >>> 14);
+
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 21;
+
+    buf[off++] = (byte) (values[2] >>> 13);
+
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 20;
+
+    buf[off++] = (byte) (values[3] >>> 12);
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 19;
+
+    buf[off++] = (byte) (values[4] >>> 11);
+
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 18;
+
+    buf[off++] = (byte) (values[5] >>> 10);
+
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 17;
+
+    buf[off++] = (byte) (values[6] >>> 9);
+
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 16;
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits24(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 16);
+    buf[off++] = (byte) (values[0] >>> 8);
+    buf[off++] = (byte) (values[0]);
+
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 16);
+    buf[off++] = (byte) (values[2] >>> 8);
+    buf[off++] = (byte) (values[2]);
+
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 16);
+    buf[off++] = (byte) (values[4] >>> 8);
+    buf[off++] = (byte) (values[4]);
+
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 16);
+    buf[off++] = (byte) (values[6] >>> 8);
+    buf[off++] = (byte) (values[6]);
+
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits25(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 17);
+
+    buf[off++] = (byte) (values[0] >>> 9);
+
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 18;
+
+    buf[off++] = (byte) (values[1] >>> 10);
+
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 19;
+
+    buf[off++] = (byte) (values[2] >>> 11);
+
+    buf[off++] = (byte) (values[2] >>> 3);
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 20;
+
+    buf[off++] = (byte) (values[3] >>> 12);
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 21;
+
+    buf[off++] = (byte) (values[4] >>> 13);
+
+    buf[off++] = (byte) (values[4] >>> 5);
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 22;
+
+    buf[off++] = (byte) (values[5] >>> 14);
+
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 23;
+
+    buf[off++] = (byte) (values[6] >>> 15);
+
+    buf[off++] = (byte) (values[6] >>> 7);
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 24;
+
+    buf[off++] = (byte) (values[7] >>> 16);
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits26(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 18);
+
+    buf[off++] = (byte) (values[0] >>> 10);
+
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 20;
+
+    buf[off++] = (byte) (values[1] >>> 12);
+
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 22;
+
+    buf[off++] = (byte) (values[2] >>> 14);
+
+    buf[off++] = (byte) (values[2] >>> 6);
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 24;
+
+    buf[off++] = (byte) (values[3] >>> 16);
+
+    buf[off++] = (byte) (values[3] >>> 8);
+
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 18);
+
+    buf[off++] = (byte) (values[4] >>> 10);
+
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 20;
+
+    buf[off++] = (byte) (values[5] >>> 12);
+
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 22;
+
+    buf[off++] = (byte) (values[6] >>> 14);
+
+    buf[off++] = (byte) (values[6] >>> 6);
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 24;
+
+    buf[off++] = (byte) (values[7] >>> 16);
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits27(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 19);
+
+    buf[off++] = (byte) (values[0] >>> 11);
+
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 22;
+
+    buf[off++] = (byte) (values[1] >>> 14);
+
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 25;
+
+    buf[off++] = (byte) (values[2] >>> 17);
+
+    buf[off++] = (byte) (values[2] >>> 9);
+
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 20;
+
+    buf[off++] = (byte) (values[3] >>> 12);
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 23;
+
+    buf[off++] = (byte) (values[4] >>> 15);
+
+    buf[off++] = (byte) (values[4] >>> 7);
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 26;
+
+    buf[off++] = (byte) (values[5] >>> 18);
+
+    buf[off++] = (byte) (values[5] >>> 10);
+
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 21;
+
+    buf[off++] = (byte) (values[6] >>> 13);
+
+    buf[off++] = (byte) (values[6] >>> 5);
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 24;
+
+    buf[off++] = (byte) (values[7] >>> 16);
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits28(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 20);
+    buf[off++] = (byte) (values[0] >>> 12);
+    buf[off++] = (byte) (values[0] >>> 4);
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 24;
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+    buf[off++] = (byte) (values[2] >>> 20);
+    buf[off++] = (byte) (values[2] >>> 12);
+    buf[off++] = (byte) (values[2] >>> 4);
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 24;
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+    buf[off++] = (byte) (values[4] >>> 20);
+    buf[off++] = (byte) (values[4] >>> 12);
+    buf[off++] = (byte) (values[4] >>> 4);
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 24;
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+    buf[off++] = (byte) (values[6] >>> 20);
+    buf[off++] = (byte) (values[6] >>> 12);
+    buf[off++] = (byte) (values[6] >>> 4);
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 24;
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits29(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 21);
+
+    buf[off++] = (byte) (values[0] >>> 13);
+
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 26;
+
+    buf[off++] = (byte) (values[1] >>> 18);
+
+    buf[off++] = (byte) (values[1] >>> 10);
+
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 23;
+
+    buf[off++] = (byte) (values[2] >>> 15);
+
+    buf[off++] = (byte) (values[2] >>> 7);
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 28;
+
+    buf[off++] = (byte) (values[3] >>> 20);
+
+    buf[off++] = (byte) (values[3] >>> 12);
+
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 25;
+
+    buf[off++] = (byte) (values[4] >>> 17);
+
+    buf[off++] = (byte) (values[4] >>> 9);
+
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 22;
+
+    buf[off++] = (byte) (values[5] >>> 14);
+
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 27;
+
+    buf[off++] = (byte) (values[6] >>> 19);
+
+    buf[off++] = (byte) (values[6] >>> 11);
+
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 24;
+
+    buf[off++] = (byte) (values[7] >>> 16);
+
+    buf[off++] = (byte) (values[7] >>> 8);
+
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits30(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 22);
+    buf[off++] = (byte) (values[0] >>> 14);
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 28;
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 26;
+    buf[off++] = (byte) (values[2] >>> 18);
+    buf[off++] = (byte) (values[2] >>> 10);
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 24;
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 22);
+    buf[off++] = (byte) (values[4] >>> 14);
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 28;
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 26;
+    buf[off++] = (byte) (values[6] >>> 18);
+    buf[off++] = (byte) (values[6] >>> 10);
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 24;
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits31(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 23);
+    buf[off++] = (byte) (values[0] >>> 15);
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 30;
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 29;
+    buf[off++] = (byte) (values[2] >>> 21);
+    buf[off++] = (byte) (values[2] >>> 13);
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 28;
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 27;
+    buf[off++] = (byte) (values[4] >>> 19);
+    buf[off++] = (byte) (values[4] >>> 11);
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 26;
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 25;
+    buf[off++] = (byte) (values[6] >>> 17);
+    buf[off++] = (byte) (values[6] >>> 9);
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 24;
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits32(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 24);
+    buf[off++] = (byte) (values[0] >>> 16);
+    buf[off++] = (byte) (values[0] >>> 8);
+    buf[off++] = (byte) (values[0]);
+
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 24);
+    buf[off++] = (byte) (values[2] >>> 16);
+    buf[off++] = (byte) (values[2] >>> 8);
+    buf[off++] = (byte) (values[2]);
+
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 24);
+    buf[off++] = (byte) (values[4] >>> 16);
+    buf[off++] = (byte) (values[4] >>> 8);
+    buf[off++] = (byte) (values[4]);
+
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 24);
+    buf[off++] = (byte) (values[6] >>> 16);
+    buf[off++] = (byte) (values[6] >>> 8);
+    buf[off++] = (byte) (values[6]);
+
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits33(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 25);
+    buf[off++] = (byte) (values[0] >>> 17);
+    buf[off++] = (byte) (values[0] >>> 9);
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 26;
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 27;
+    buf[off++] = (byte) (values[2] >>> 19);
+    buf[off++] = (byte) (values[2] >>> 11);
+    buf[off++] = (byte) (values[2] >>> 3);
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 28;
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 29;
+    buf[off++] = (byte) (values[4] >>> 21);
+    buf[off++] = (byte) (values[4] >>> 13);
+    buf[off++] = (byte) (values[4] >>> 5);
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 30;
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 31;
+    buf[off++] = (byte) (values[6] >>> 23);
+    buf[off++] = (byte) (values[6] >>> 15);
+    buf[off++] = (byte) (values[6] >>> 7);
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits34(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 26);
+    buf[off++] = (byte) (values[0] >>> 18);
+    buf[off++] = (byte) (values[0] >>> 10);
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 28;
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 30;
+    buf[off++] = (byte) (values[2] >>> 22);
+    buf[off++] = (byte) (values[2] >>> 14);
+    buf[off++] = (byte) (values[2] >>> 6);
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 32;
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 26);
+    buf[off++] = (byte) (values[4] >>> 18);
+    buf[off++] = (byte) (values[4] >>> 10);
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 28;
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 30;
+    buf[off++] = (byte) (values[6] >>> 22);
+    buf[off++] = (byte) (values[6] >>> 14);
+    buf[off++] = (byte) (values[6] >>> 6);
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits35(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 27);
+    buf[off++] = (byte) (values[0] >>> 19);
+    buf[off++] = (byte) (values[0] >>> 11);
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 30;
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 33;
+    buf[off++] = (byte) (values[2] >>> 25);
+    buf[off++] = (byte) (values[2] >>> 17);
+    buf[off++] = (byte) (values[2] >>> 9);
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 28;
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 31;
+    buf[off++] = (byte) (values[4] >>> 23);
+    buf[off++] = (byte) (values[4] >>> 15);
+    buf[off++] = (byte) (values[4] >>> 7);
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 34;
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 29;
+    buf[off++] = (byte) (values[6] >>> 21);
+    buf[off++] = (byte) (values[6] >>> 13);
+    buf[off++] = (byte) (values[6] >>> 5);
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits36(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 28);
+    buf[off++] = (byte) (values[0] >>> 20);
+    buf[off++] = (byte) (values[0] >>> 12);
+    buf[off++] = (byte) (values[0] >>> 4);
+
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 32;
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 28);
+    buf[off++] = (byte) (values[2] >>> 20);
+    buf[off++] = (byte) (values[2] >>> 12);
+    buf[off++] = (byte) (values[2] >>> 4);
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 32;
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 28);
+    buf[off++] = (byte) (values[4] >>> 20);
+    buf[off++] = (byte) (values[4] >>> 12);
+    buf[off++] = (byte) (values[4] >>> 4);
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 32;
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 28);
+    buf[off++] = (byte) (values[6] >>> 20);
+    buf[off++] = (byte) (values[6] >>> 12);
+    buf[off++] = (byte) (values[6] >>> 4);
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits37(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 29);
+    buf[off++] = (byte) (values[0] >>> 21);
+    buf[off++] = (byte) (values[0] >>> 13);
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 34;
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 31;
+    buf[off++] = (byte) (values[2] >>> 23);
+    buf[off++] = (byte) (values[2] >>> 15);
+    buf[off++] = (byte) (values[2] >>> 7);
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 36;
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 33;
+    buf[off++] = (byte) (values[4] >>> 25);
+    buf[off++] = (byte) (values[4] >>> 17);
+    buf[off++] = (byte) (values[4] >>> 9);
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 30;
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 35;
+    buf[off++] = (byte) (values[6] >>> 27);
+    buf[off++] = (byte) (values[6] >>> 19);
+    buf[off++] = (byte) (values[6] >>> 11);
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits38(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 30);
+    buf[off++] = (byte) (values[0] >>> 22);
+    buf[off++] = (byte) (values[0] >>> 14);
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 36;
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 34;
+    buf[off++] = (byte) (values[2] >>> 26);
+    buf[off++] = (byte) (values[2] >>> 18);
+    buf[off++] = (byte) (values[2] >>> 10);
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 32;
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 30);
+    buf[off++] = (byte) (values[4] >>> 22);
+    buf[off++] = (byte) (values[4] >>> 14);
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 36;
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 34;
+    buf[off++] = (byte) (values[6] >>> 26);
+    buf[off++] = (byte) (values[6] >>> 18);
+    buf[off++] = (byte) (values[6] >>> 10);
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits39(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 31);
+    buf[off++] = (byte) (values[0] >>> 23);
+    buf[off++] = (byte) (values[0] >>> 15);
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 38;
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 37;
+    buf[off++] = (byte) (values[2] >>> 29);
+    buf[off++] = (byte) (values[2] >>> 21);
+    buf[off++] = (byte) (values[2] >>> 13);
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 36;
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 35;
+    buf[off++] = (byte) (values[4] >>> 27);
+    buf[off++] = (byte) (values[4] >>> 19);
+    buf[off++] = (byte) (values[4] >>> 11);
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 34;
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 33;
+    buf[off++] = (byte) (values[6] >>> 25);
+    buf[off++] = (byte) (values[6] >>> 17);
+    buf[off++] = (byte) (values[6] >>> 9);
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 32;
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits40(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 32);
+    buf[off++] = (byte) (values[0] >>> 24);
+    buf[off++] = (byte) (values[0] >>> 16);
+    buf[off++] = (byte) (values[0] >>> 8);
+    buf[off++] = (byte) (values[0]);
+
+    buf[off++] = (byte) (values[1] >>> 32);
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 32);
+    buf[off++] = (byte) (values[2] >>> 24);
+    buf[off++] = (byte) (values[2] >>> 16);
+    buf[off++] = (byte) (values[2] >>> 8);
+    buf[off++] = (byte) (values[2]);
+
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 32);
+    buf[off++] = (byte) (values[4] >>> 24);
+    buf[off++] = (byte) (values[4] >>> 16);
+    buf[off++] = (byte) (values[4] >>> 8);
+    buf[off++] = (byte) (values[4]);
+
+    buf[off++] = (byte) (values[5] >>> 32);
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 32);
+    buf[off++] = (byte) (values[6] >>> 24);
+    buf[off++] = (byte) (values[6] >>> 16);
+    buf[off++] = (byte) (values[6] >>> 8);
+    buf[off++] = (byte) (values[6]);
+
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits41(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 33);
+    buf[off++] = (byte) (values[0] >>> 25);
+    buf[off++] = (byte) (values[0] >>> 17);
+    buf[off++] = (byte) (values[0] >>> 9);
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 34;
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 35;
+    buf[off++] = (byte) (values[2] >>> 27);
+    buf[off++] = (byte) (values[2] >>> 19);
+    buf[off++] = (byte) (values[2] >>> 11);
+    buf[off++] = (byte) (values[2] >>> 3);
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 36;
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 37;
+    buf[off++] = (byte) (values[4] >>> 29);
+    buf[off++] = (byte) (values[4] >>> 21);
+    buf[off++] = (byte) (values[4] >>> 13);
+    buf[off++] = (byte) (values[4] >>> 5);
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 38;
+    buf[off++] = (byte) (values[5] >>> 30);
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 39;
+    buf[off++] = (byte) (values[6] >>> 31);
+    buf[off++] = (byte) (values[6] >>> 23);
+    buf[off++] = (byte) (values[6] >>> 15);
+    buf[off++] = (byte) (values[6] >>> 7);
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits42(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 34);
+    buf[off++] = (byte) (values[0] >>> 26);
+    buf[off++] = (byte) (values[0] >>> 18);
+    buf[off++] = (byte) (values[0] >>> 10);
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 36;
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 38;
+    buf[off++] = (byte) (values[2] >>> 30);
+    buf[off++] = (byte) (values[2] >>> 22);
+    buf[off++] = (byte) (values[2] >>> 14);
+    buf[off++] = (byte) (values[2] >>> 6);
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 40;
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 34);
+    buf[off++] = (byte) (values[4] >>> 26);
+    buf[off++] = (byte) (values[4] >>> 18);
+    buf[off++] = (byte) (values[4] >>> 10);
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 36;
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 38;
+    buf[off++] = (byte) (values[6] >>> 30);
+    buf[off++] = (byte) (values[6] >>> 22);
+    buf[off++] = (byte) (values[6] >>> 14);
+    buf[off++] = (byte) (values[6] >>> 6);
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits43(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 35);
+    buf[off++] = (byte) (values[0] >>> 27);
+    buf[off++] = (byte) (values[0] >>> 19);
+    buf[off++] = (byte) (values[0] >>> 11);
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 38;
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 41;
+    buf[off++] = (byte) (values[2] >>> 33);
+    buf[off++] = (byte) (values[2] >>> 25);
+    buf[off++] = (byte) (values[2] >>> 17);
+    buf[off++] = (byte) (values[2] >>> 9);
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 36;
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 39;
+    buf[off++] = (byte) (values[4] >>> 31);
+    buf[off++] = (byte) (values[4] >>> 23);
+    buf[off++] = (byte) (values[4] >>> 15);
+    buf[off++] = (byte) (values[4] >>> 7);
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 42;
+    buf[off++] = (byte) (values[5] >>> 34);
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 37;
+    buf[off++] = (byte) (values[6] >>> 29);
+    buf[off++] = (byte) (values[6] >>> 21);
+    buf[off++] = (byte) (values[6] >>> 13);
+    buf[off++] = (byte) (values[6] >>> 5);
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits44(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 36);
+    buf[off++] = (byte) (values[0] >>> 28);
+    buf[off++] = (byte) (values[0] >>> 20);
+    buf[off++] = (byte) (values[0] >>> 12);
+    buf[off++] = (byte) (values[0] >>> 4);
+
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 40;
+    buf[off++] = (byte) (values[1] >>> 32);
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 36);
+    buf[off++] = (byte) (values[2] >>> 28);
+    buf[off++] = (byte) (values[2] >>> 20);
+    buf[off++] = (byte) (values[2] >>> 12);
+    buf[off++] = (byte) (values[2] >>> 4);
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 40;
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 36);
+    buf[off++] = (byte) (values[4] >>> 28);
+    buf[off++] = (byte) (values[4] >>> 20);
+    buf[off++] = (byte) (values[4] >>> 12);
+    buf[off++] = (byte) (values[4] >>> 4);
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 40;
+    buf[off++] = (byte) (values[5] >>> 32);
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 36);
+    buf[off++] = (byte) (values[6] >>> 28);
+    buf[off++] = (byte) (values[6] >>> 20);
+    buf[off++] = (byte) (values[6] >>> 12);
+    buf[off++] = (byte) (values[6] >>> 4);
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits45(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 37);
+    buf[off++] = (byte) (values[0] >>> 29);
+    buf[off++] = (byte) (values[0] >>> 21);
+    buf[off++] = (byte) (values[0] >>> 13);
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 42;
+    buf[off++] = (byte) (values[1] >>> 34);
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 39;
+    buf[off++] = (byte) (values[2] >>> 31);
+    buf[off++] = (byte) (values[2] >>> 23);
+    buf[off++] = (byte) (values[2] >>> 15);
+    buf[off++] = (byte) (values[2] >>> 7);
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 44;
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 41;
+    buf[off++] = (byte) (values[4] >>> 33);
+    buf[off++] = (byte) (values[4] >>> 25);
+    buf[off++] = (byte) (values[4] >>> 17);
+    buf[off++] = (byte) (values[4] >>> 9);
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 38;
+    buf[off++] = (byte) (values[5] >>> 30);
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 43;
+    buf[off++] = (byte) (values[6] >>> 35);
+    buf[off++] = (byte) (values[6] >>> 27);
+    buf[off++] = (byte) (values[6] >>> 19);
+    buf[off++] = (byte) (values[6] >>> 11);
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits46(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 38);
+    buf[off++] = (byte) (values[0] >>> 30);
+    buf[off++] = (byte) (values[0] >>> 22);
+    buf[off++] = (byte) (values[0] >>> 14);
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 44;
+    buf[off++] = (byte) (values[1] >>> 36);
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 42;
+    buf[off++] = (byte) (values[2] >>> 34);
+    buf[off++] = (byte) (values[2] >>> 26);
+    buf[off++] = (byte) (values[2] >>> 18);
+    buf[off++] = (byte) (values[2] >>> 10);
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 40;
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 38);
+    buf[off++] = (byte) (values[4] >>> 30);
+    buf[off++] = (byte) (values[4] >>> 22);
+    buf[off++] = (byte) (values[4] >>> 14);
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 44;
+    buf[off++] = (byte) (values[5] >>> 36);
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 42;
+    buf[off++] = (byte) (values[6] >>> 34);
+    buf[off++] = (byte) (values[6] >>> 26);
+    buf[off++] = (byte) (values[6] >>> 18);
+    buf[off++] = (byte) (values[6] >>> 10);
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits47(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 39);
+    buf[off++] = (byte) (values[0] >>> 31);
+    buf[off++] = (byte) (values[0] >>> 23);
+    buf[off++] = (byte) (values[0] >>> 15);
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 46;
+    buf[off++] = (byte) (values[1] >>> 38);
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 45;
+    buf[off++] = (byte) (values[2] >>> 37);
+    buf[off++] = (byte) (values[2] >>> 29);
+    buf[off++] = (byte) (values[2] >>> 21);
+    buf[off++] = (byte) (values[2] >>> 13);
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 44;
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 43;
+    buf[off++] = (byte) (values[4] >>> 35);
+    buf[off++] = (byte) (values[4] >>> 27);
+    buf[off++] = (byte) (values[4] >>> 19);
+    buf[off++] = (byte) (values[4] >>> 11);
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 42;
+    buf[off++] = (byte) (values[5] >>> 34);
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 41;
+    buf[off++] = (byte) (values[6] >>> 33);
+    buf[off++] = (byte) (values[6] >>> 25);
+    buf[off++] = (byte) (values[6] >>> 17);
+    buf[off++] = (byte) (values[6] >>> 9);
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 40;
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits48(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 40);
+    buf[off++] = (byte) (values[0] >>> 32);
+    buf[off++] = (byte) (values[0] >>> 24);
+    buf[off++] = (byte) (values[0] >>> 16);
+    buf[off++] = (byte) (values[0] >>> 8);
+    buf[off++] = (byte) (values[0]);
+
+    buf[off++] = (byte) (values[1] >>> 40);
+    buf[off++] = (byte) (values[1] >>> 32);
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 40);
+    buf[off++] = (byte) (values[2] >>> 32);
+    buf[off++] = (byte) (values[2] >>> 24);
+    buf[off++] = (byte) (values[2] >>> 16);
+    buf[off++] = (byte) (values[2] >>> 8);
+    buf[off++] = (byte) (values[2]);
+
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 40);
+    buf[off++] = (byte) (values[4] >>> 32);
+    buf[off++] = (byte) (values[4] >>> 24);
+    buf[off++] = (byte) (values[4] >>> 16);
+    buf[off++] = (byte) (values[4] >>> 8);
+    buf[off++] = (byte) (values[4]);
+
+    buf[off++] = (byte) (values[5] >>> 40);
+    buf[off++] = (byte) (values[5] >>> 32);
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 40);
+    buf[off++] = (byte) (values[6] >>> 32);
+    buf[off++] = (byte) (values[6] >>> 24);
+    buf[off++] = (byte) (values[6] >>> 16);
+    buf[off++] = (byte) (values[6] >>> 8);
+    buf[off++] = (byte) (values[6]);
+
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits49(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 41);
+    buf[off++] = (byte) (values[0] >>> 33);
+    buf[off++] = (byte) (values[0] >>> 25);
+    buf[off++] = (byte) (values[0] >>> 17);
+    buf[off++] = (byte) (values[0] >>> 9);
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 42;
+    buf[off++] = (byte) (values[1] >>> 34);
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 43;
+    buf[off++] = (byte) (values[2] >>> 35);
+    buf[off++] = (byte) (values[2] >>> 27);
+    buf[off++] = (byte) (values[2] >>> 19);
+    buf[off++] = (byte) (values[2] >>> 11);
+    buf[off++] = (byte) (values[2] >>> 3);
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 44;
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 45;
+    buf[off++] = (byte) (values[4] >>> 37);
+    buf[off++] = (byte) (values[4] >>> 29);
+    buf[off++] = (byte) (values[4] >>> 21);
+    buf[off++] = (byte) (values[4] >>> 13);
+    buf[off++] = (byte) (values[4] >>> 5);
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 46;
+    buf[off++] = (byte) (values[5] >>> 38);
+    buf[off++] = (byte) (values[5] >>> 30);
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 47;
+    buf[off++] = (byte) (values[6] >>> 39);
+    buf[off++] = (byte) (values[6] >>> 31);
+    buf[off++] = (byte) (values[6] >>> 23);
+    buf[off++] = (byte) (values[6] >>> 15);
+    buf[off++] = (byte) (values[6] >>> 7);
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits50(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 42);
+    buf[off++] = (byte) (values[0] >>> 34);
+    buf[off++] = (byte) (values[0] >>> 26);
+    buf[off++] = (byte) (values[0] >>> 18);
+    buf[off++] = (byte) (values[0] >>> 10);
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 44;
+    buf[off++] = (byte) (values[1] >>> 36);
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 46;
+    buf[off++] = (byte) (values[2] >>> 38);
+    buf[off++] = (byte) (values[2] >>> 30);
+    buf[off++] = (byte) (values[2] >>> 22);
+    buf[off++] = (byte) (values[2] >>> 14);
+    buf[off++] = (byte) (values[2] >>> 6);
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 48;
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 42);
+    buf[off++] = (byte) (values[4] >>> 34);
+    buf[off++] = (byte) (values[4] >>> 26);
+    buf[off++] = (byte) (values[4] >>> 18);
+    buf[off++] = (byte) (values[4] >>> 10);
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 44;
+    buf[off++] = (byte) (values[5] >>> 36);
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 46;
+    buf[off++] = (byte) (values[6] >>> 38);
+    buf[off++] = (byte) (values[6] >>> 30);
+    buf[off++] = (byte) (values[6] >>> 22);
+    buf[off++] = (byte) (values[6] >>> 14);
+    buf[off++] = (byte) (values[6] >>> 6);
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits51(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 43);
+    buf[off++] = (byte) (values[0] >>> 35);
+    buf[off++] = (byte) (values[0] >>> 27);
+    buf[off++] = (byte) (values[0] >>> 19);
+    buf[off++] = (byte) (values[0] >>> 11);
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 46;
+    buf[off++] = (byte) (values[1] >>> 38);
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 49;
+    buf[off++] = (byte) (values[2] >>> 41);
+    buf[off++] = (byte) (values[2] >>> 33);
+    buf[off++] = (byte) (values[2] >>> 25);
+    buf[off++] = (byte) (values[2] >>> 17);
+    buf[off++] = (byte) (values[2] >>> 9);
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 44;
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 47;
+    buf[off++] = (byte) (values[4] >>> 39);
+    buf[off++] = (byte) (values[4] >>> 31);
+    buf[off++] = (byte) (values[4] >>> 23);
+    buf[off++] = (byte) (values[4] >>> 15);
+    buf[off++] = (byte) (values[4] >>> 7);
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 50;
+    buf[off++] = (byte) (values[5] >>> 42);
+    buf[off++] = (byte) (values[5] >>> 34);
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 45;
+    buf[off++] = (byte) (values[6] >>> 37);
+    buf[off++] = (byte) (values[6] >>> 29);
+    buf[off++] = (byte) (values[6] >>> 21);
+    buf[off++] = (byte) (values[6] >>> 13);
+    buf[off++] = (byte) (values[6] >>> 5);
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits52(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 44);
+    buf[off++] = (byte) (values[0] >>> 36);
+    buf[off++] = (byte) (values[0] >>> 28);
+    buf[off++] = (byte) (values[0] >>> 20);
+    buf[off++] = (byte) (values[0] >>> 12);
+    buf[off++] = (byte) (values[0] >>> 4);
+
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 48;
+    buf[off++] = (byte) (values[1] >>> 40);
+    buf[off++] = (byte) (values[1] >>> 32);
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 44);
+    buf[off++] = (byte) (values[2] >>> 36);
+    buf[off++] = (byte) (values[2] >>> 28);
+    buf[off++] = (byte) (values[2] >>> 20);
+    buf[off++] = (byte) (values[2] >>> 12);
+    buf[off++] = (byte) (values[2] >>> 4);
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 48;
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 44);
+    buf[off++] = (byte) (values[4] >>> 36);
+    buf[off++] = (byte) (values[4] >>> 28);
+    buf[off++] = (byte) (values[4] >>> 20);
+    buf[off++] = (byte) (values[4] >>> 12);
+    buf[off++] = (byte) (values[4] >>> 4);
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 48;
+    buf[off++] = (byte) (values[5] >>> 40);
+    buf[off++] = (byte) (values[5] >>> 32);
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 44);
+    buf[off++] = (byte) (values[6] >>> 36);
+    buf[off++] = (byte) (values[6] >>> 28);
+    buf[off++] = (byte) (values[6] >>> 20);
+    buf[off++] = (byte) (values[6] >>> 12);
+    buf[off++] = (byte) (values[6] >>> 4);
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits53(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 45);
+    buf[off++] = (byte) (values[0] >>> 37);
+    buf[off++] = (byte) (values[0] >>> 29);
+    buf[off++] = (byte) (values[0] >>> 21);
+    buf[off++] = (byte) (values[0] >>> 13);
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 50;
+    buf[off++] = (byte) (values[1] >>> 42);
+    buf[off++] = (byte) (values[1] >>> 34);
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 47;
+    buf[off++] = (byte) (values[2] >>> 39);
+    buf[off++] = (byte) (values[2] >>> 31);
+    buf[off++] = (byte) (values[2] >>> 23);
+    buf[off++] = (byte) (values[2] >>> 15);
+    buf[off++] = (byte) (values[2] >>> 7);
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 52;
+    buf[off++] = (byte) (values[3] >>> 44);
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 49;
+    buf[off++] = (byte) (values[4] >>> 41);
+    buf[off++] = (byte) (values[4] >>> 33);
+    buf[off++] = (byte) (values[4] >>> 25);
+    buf[off++] = (byte) (values[4] >>> 17);
+    buf[off++] = (byte) (values[4] >>> 9);
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 46;
+    buf[off++] = (byte) (values[5] >>> 38);
+    buf[off++] = (byte) (values[5] >>> 30);
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 51;
+    buf[off++] = (byte) (values[6] >>> 43);
+    buf[off++] = (byte) (values[6] >>> 35);
+    buf[off++] = (byte) (values[6] >>> 27);
+    buf[off++] = (byte) (values[6] >>> 19);
+    buf[off++] = (byte) (values[6] >>> 11);
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits54(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 46);
+    buf[off++] = (byte) (values[0] >>> 38);
+    buf[off++] = (byte) (values[0] >>> 30);
+    buf[off++] = (byte) (values[0] >>> 22);
+    buf[off++] = (byte) (values[0] >>> 14);
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 52;
+    buf[off++] = (byte) (values[1] >>> 44);
+    buf[off++] = (byte) (values[1] >>> 36);
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 50;
+    buf[off++] = (byte) (values[2] >>> 42);
+    buf[off++] = (byte) (values[2] >>> 34);
+    buf[off++] = (byte) (values[2] >>> 26);
+    buf[off++] = (byte) (values[2] >>> 18);
+    buf[off++] = (byte) (values[2] >>> 10);
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 48;
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 46);
+    buf[off++] = (byte) (values[4] >>> 38);
+    buf[off++] = (byte) (values[4] >>> 30);
+    buf[off++] = (byte) (values[4] >>> 22);
+    buf[off++] = (byte) (values[4] >>> 14);
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 52;
+    buf[off++] = (byte) (values[5] >>> 44);
+    buf[off++] = (byte) (values[5] >>> 36);
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 50;
+    buf[off++] = (byte) (values[6] >>> 42);
+    buf[off++] = (byte) (values[6] >>> 34);
+    buf[off++] = (byte) (values[6] >>> 26);
+    buf[off++] = (byte) (values[6] >>> 18);
+    buf[off++] = (byte) (values[6] >>> 10);
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits55(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 47);
+    buf[off++] = (byte) (values[0] >>> 39);
+    buf[off++] = (byte) (values[0] >>> 31);
+    buf[off++] = (byte) (values[0] >>> 23);
+    buf[off++] = (byte) (values[0] >>> 15);
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 54;
+    buf[off++] = (byte) (values[1] >>> 46);
+    buf[off++] = (byte) (values[1] >>> 38);
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 53;
+    buf[off++] = (byte) (values[2] >>> 45);
+    buf[off++] = (byte) (values[2] >>> 37);
+    buf[off++] = (byte) (values[2] >>> 29);
+    buf[off++] = (byte) (values[2] >>> 21);
+    buf[off++] = (byte) (values[2] >>> 13);
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 52;
+    buf[off++] = (byte) (values[3] >>> 44);
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 51;
+    buf[off++] = (byte) (values[4] >>> 43);
+    buf[off++] = (byte) (values[4] >>> 35);
+    buf[off++] = (byte) (values[4] >>> 27);
+    buf[off++] = (byte) (values[4] >>> 19);
+    buf[off++] = (byte) (values[4] >>> 11);
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 50;
+    buf[off++] = (byte) (values[5] >>> 42);
+    buf[off++] = (byte) (values[5] >>> 34);
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 49;
+    buf[off++] = (byte) (values[6] >>> 41);
+    buf[off++] = (byte) (values[6] >>> 33);
+    buf[off++] = (byte) (values[6] >>> 25);
+    buf[off++] = (byte) (values[6] >>> 17);
+    buf[off++] = (byte) (values[6] >>> 9);
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 48;
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits56(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 48);
+    buf[off++] = (byte) (values[0] >>> 40);
+    buf[off++] = (byte) (values[0] >>> 32);
+    buf[off++] = (byte) (values[0] >>> 24);
+    buf[off++] = (byte) (values[0] >>> 16);
+    buf[off++] = (byte) (values[0] >>> 8);
+    buf[off++] = (byte) (values[0]);
+
+    buf[off++] = (byte) (values[1] >>> 48);
+    buf[off++] = (byte) (values[1] >>> 40);
+    buf[off++] = (byte) (values[1] >>> 32);
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 48);
+    buf[off++] = (byte) (values[2] >>> 40);
+    buf[off++] = (byte) (values[2] >>> 32);
+    buf[off++] = (byte) (values[2] >>> 24);
+    buf[off++] = (byte) (values[2] >>> 16);
+    buf[off++] = (byte) (values[2] >>> 8);
+    buf[off++] = (byte) (values[2]);
+
+    buf[off++] = (byte) (values[3] >>> 48);
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 48);
+    buf[off++] = (byte) (values[4] >>> 40);
+    buf[off++] = (byte) (values[4] >>> 32);
+    buf[off++] = (byte) (values[4] >>> 24);
+    buf[off++] = (byte) (values[4] >>> 16);
+    buf[off++] = (byte) (values[4] >>> 8);
+    buf[off++] = (byte) (values[4]);
+
+    buf[off++] = (byte) (values[5] >>> 48);
+    buf[off++] = (byte) (values[5] >>> 40);
+    buf[off++] = (byte) (values[5] >>> 32);
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 48);
+    buf[off++] = (byte) (values[6] >>> 40);
+    buf[off++] = (byte) (values[6] >>> 32);
+    buf[off++] = (byte) (values[6] >>> 24);
+    buf[off++] = (byte) (values[6] >>> 16);
+    buf[off++] = (byte) (values[6] >>> 8);
+    buf[off++] = (byte) (values[6]);
+
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits57(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 49);
+    buf[off++] = (byte) (values[0] >>> 41);
+    buf[off++] = (byte) (values[0] >>> 33);
+    buf[off++] = (byte) (values[0] >>> 25);
+    buf[off++] = (byte) (values[0] >>> 17);
+    buf[off++] = (byte) (values[0] >>> 9);
+    buf[off++] = (byte) (values[0] >>> 1);
+
+    buf[off] = (byte) (values[0] << 7);
+    buf[off++] |= values[1] >>> 50;
+    buf[off++] = (byte) (values[1] >>> 42);
+    buf[off++] = (byte) (values[1] >>> 34);
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 51;
+    buf[off++] = (byte) (values[2] >>> 43);
+    buf[off++] = (byte) (values[2] >>> 35);
+    buf[off++] = (byte) (values[2] >>> 27);
+    buf[off++] = (byte) (values[2] >>> 19);
+    buf[off++] = (byte) (values[2] >>> 11);
+    buf[off++] = (byte) (values[2] >>> 3);
+
+    buf[off] = (byte) (values[2] << 5);
+    buf[off++] |= values[3] >>> 52;
+    buf[off++] = (byte) (values[3] >>> 44);
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 53;
+    buf[off++] = (byte) (values[4] >>> 45);
+    buf[off++] = (byte) (values[4] >>> 37);
+    buf[off++] = (byte) (values[4] >>> 29);
+    buf[off++] = (byte) (values[4] >>> 21);
+    buf[off++] = (byte) (values[4] >>> 13);
+    buf[off++] = (byte) (values[4] >>> 5);
+
+    buf[off] = (byte) (values[4] << 3);
+    buf[off++] |= values[5] >>> 54;
+    buf[off++] = (byte) (values[5] >>> 46);
+    buf[off++] = (byte) (values[5] >>> 38);
+    buf[off++] = (byte) (values[5] >>> 30);
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 55;
+    buf[off++] = (byte) (values[6] >>> 47);
+    buf[off++] = (byte) (values[6] >>> 39);
+    buf[off++] = (byte) (values[6] >>> 31);
+    buf[off++] = (byte) (values[6] >>> 23);
+    buf[off++] = (byte) (values[6] >>> 15);
+    buf[off++] = (byte) (values[6] >>> 7);
+
+    buf[off] = (byte) (values[6] << 1);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits58(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 50);
+    buf[off++] = (byte) (values[0] >>> 42);
+    buf[off++] = (byte) (values[0] >>> 34);
+    buf[off++] = (byte) (values[0] >>> 26);
+    buf[off++] = (byte) (values[0] >>> 18);
+    buf[off++] = (byte) (values[0] >>> 10);
+    buf[off++] = (byte) (values[0] >>> 2);
+
+    buf[off] = (byte) (values[0] << 6);
+    buf[off++] |= values[1] >>> 52;
+    buf[off++] = (byte) (values[1] >>> 44);
+    buf[off++] = (byte) (values[1] >>> 36);
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 54;
+    buf[off++] = (byte) (values[2] >>> 46);
+    buf[off++] = (byte) (values[2] >>> 38);
+    buf[off++] = (byte) (values[2] >>> 30);
+    buf[off++] = (byte) (values[2] >>> 22);
+    buf[off++] = (byte) (values[2] >>> 14);
+    buf[off++] = (byte) (values[2] >>> 6);
+
+    buf[off] = (byte) (values[2] << 2);
+    buf[off++] |= values[3] >>> 56;
+    buf[off++] = (byte) (values[3] >>> 48);
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 50);
+    buf[off++] = (byte) (values[4] >>> 42);
+    buf[off++] = (byte) (values[4] >>> 34);
+    buf[off++] = (byte) (values[4] >>> 26);
+    buf[off++] = (byte) (values[4] >>> 18);
+    buf[off++] = (byte) (values[4] >>> 10);
+    buf[off++] = (byte) (values[4] >>> 2);
+
+    buf[off] = (byte) (values[4] << 6);
+    buf[off++] |= values[5] >>> 52;
+    buf[off++] = (byte) (values[5] >>> 44);
+    buf[off++] = (byte) (values[5] >>> 36);
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 54;
+    buf[off++] = (byte) (values[6] >>> 46);
+    buf[off++] = (byte) (values[6] >>> 38);
+    buf[off++] = (byte) (values[6] >>> 30);
+    buf[off++] = (byte) (values[6] >>> 22);
+    buf[off++] = (byte) (values[6] >>> 14);
+    buf[off++] = (byte) (values[6] >>> 6);
+
+    buf[off] = (byte) (values[6] << 2);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits59(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 51);
+    buf[off++] = (byte) (values[0] >>> 43);
+    buf[off++] = (byte) (values[0] >>> 35);
+    buf[off++] = (byte) (values[0] >>> 27);
+    buf[off++] = (byte) (values[0] >>> 19);
+    buf[off++] = (byte) (values[0] >>> 11);
+    buf[off++] = (byte) (values[0] >>> 3);
+
+    buf[off] = (byte) (values[0] << 5);
+    buf[off++] |= values[1] >>> 54;
+    buf[off++] = (byte) (values[1] >>> 46);
+    buf[off++] = (byte) (values[1] >>> 38);
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 57;
+    buf[off++] = (byte) (values[2] >>> 49);
+    buf[off++] = (byte) (values[2] >>> 41);
+    buf[off++] = (byte) (values[2] >>> 33);
+    buf[off++] = (byte) (values[2] >>> 25);
+    buf[off++] = (byte) (values[2] >>> 17);
+    buf[off++] = (byte) (values[2] >>> 9);
+    buf[off++] = (byte) (values[2] >>> 1);
+
+    buf[off] = (byte) (values[2] << 7);
+    buf[off++] |= values[3] >>> 52;
+    buf[off++] = (byte) (values[3] >>> 44);
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 55;
+    buf[off++] = (byte) (values[4] >>> 47);
+    buf[off++] = (byte) (values[4] >>> 39);
+    buf[off++] = (byte) (values[4] >>> 31);
+    buf[off++] = (byte) (values[4] >>> 23);
+    buf[off++] = (byte) (values[4] >>> 15);
+    buf[off++] = (byte) (values[4] >>> 7);
+
+    buf[off] = (byte) (values[4] << 1);
+    buf[off++] |= values[5] >>> 58;
+    buf[off++] = (byte) (values[5] >>> 50);
+    buf[off++] = (byte) (values[5] >>> 42);
+    buf[off++] = (byte) (values[5] >>> 34);
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 53;
+    buf[off++] = (byte) (values[6] >>> 45);
+    buf[off++] = (byte) (values[6] >>> 37);
+    buf[off++] = (byte) (values[6] >>> 29);
+    buf[off++] = (byte) (values[6] >>> 21);
+    buf[off++] = (byte) (values[6] >>> 13);
+    buf[off++] = (byte) (values[6] >>> 5);
+
+    buf[off] = (byte) (values[6] << 3);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits60(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 52);
+    buf[off++] = (byte) (values[0] >>> 44);
+    buf[off++] = (byte) (values[0] >>> 36);
+    buf[off++] = (byte) (values[0] >>> 28);
+    buf[off++] = (byte) (values[0] >>> 20);
+    buf[off++] = (byte) (values[0] >>> 12);
+    buf[off++] = (byte) (values[0] >>> 4);
+
+    buf[off] = (byte) (values[0] << 4);
+    buf[off++] |= values[1] >>> 56;
+    buf[off++] = (byte) (values[1] >>> 48);
+    buf[off++] = (byte) (values[1] >>> 40);
+    buf[off++] = (byte) (values[1] >>> 32);
+    buf[off++] = (byte) (values[1] >>> 24);
+    buf[off++] = (byte) (values[1] >>> 16);
+    buf[off++] = (byte) (values[1] >>> 8);
+    buf[off++] = (byte) (values[1]);
+
+    buf[off++] = (byte) (values[2] >>> 52);
+    buf[off++] = (byte) (values[2] >>> 44);
+    buf[off++] = (byte) (values[2] >>> 36);
+    buf[off++] = (byte) (values[2] >>> 28);
+    buf[off++] = (byte) (values[2] >>> 20);
+    buf[off++] = (byte) (values[2] >>> 12);
+    buf[off++] = (byte) (values[2] >>> 4);
+
+    buf[off] = (byte) (values[2] << 4);
+    buf[off++] |= values[3] >>> 56;
+    buf[off++] = (byte) (values[3] >>> 48);
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 52);
+    buf[off++] = (byte) (values[4] >>> 44);
+    buf[off++] = (byte) (values[4] >>> 36);
+    buf[off++] = (byte) (values[4] >>> 28);
+    buf[off++] = (byte) (values[4] >>> 20);
+    buf[off++] = (byte) (values[4] >>> 12);
+    buf[off++] = (byte) (values[4] >>> 4);
+
+    buf[off] = (byte) (values[4] << 4);
+    buf[off++] |= values[5] >>> 56;
+    buf[off++] = (byte) (values[5] >>> 48);
+    buf[off++] = (byte) (values[5] >>> 40);
+    buf[off++] = (byte) (values[5] >>> 32);
+    buf[off++] = (byte) (values[5] >>> 24);
+    buf[off++] = (byte) (values[5] >>> 16);
+    buf[off++] = (byte) (values[5] >>> 8);
+    buf[off++] = (byte) (values[5]);
+
+    buf[off++] = (byte) (values[6] >>> 52);
+    buf[off++] = (byte) (values[6] >>> 44);
+    buf[off++] = (byte) (values[6] >>> 36);
+    buf[off++] = (byte) (values[6] >>> 28);
+    buf[off++] = (byte) (values[6] >>> 20);
+    buf[off++] = (byte) (values[6] >>> 12);
+    buf[off++] = (byte) (values[6] >>> 4);
+
+    buf[off] = (byte) (values[6] << 4);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits61(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 53);
+    buf[off++] = (byte) (values[0] >>> 45);
+    buf[off++] = (byte) (values[0] >>> 37);
+    buf[off++] = (byte) (values[0] >>> 29);
+    buf[off++] = (byte) (values[0] >>> 21);
+    buf[off++] = (byte) (values[0] >>> 13);
+    buf[off++] = (byte) (values[0] >>> 5);
+
+    buf[off] = (byte) (values[0] << 3);
+    buf[off++] |= values[1] >>> 58;
+    buf[off++] = (byte) (values[1] >>> 50);
+    buf[off++] = (byte) (values[1] >>> 42);
+    buf[off++] = (byte) (values[1] >>> 34);
+    buf[off++] = (byte) (values[1] >>> 26);
+    buf[off++] = (byte) (values[1] >>> 18);
+    buf[off++] = (byte) (values[1] >>> 10);
+    buf[off++] = (byte) (values[1] >>> 2);
+
+    buf[off] = (byte) (values[1] << 6);
+    buf[off++] |= values[2] >>> 55;
+    buf[off++] = (byte) (values[2] >>> 47);
+    buf[off++] = (byte) (values[2] >>> 39);
+    buf[off++] = (byte) (values[2] >>> 31);
+    buf[off++] = (byte) (values[2] >>> 23);
+    buf[off++] = (byte) (values[2] >>> 15);
+    buf[off++] = (byte) (values[2] >>> 7);
+
+    buf[off] = (byte) (values[2] << 1);
+    buf[off++] |= values[3] >>> 60;
+    buf[off++] = (byte) (values[3] >>> 52);
+    buf[off++] = (byte) (values[3] >>> 44);
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 57;
+    buf[off++] = (byte) (values[4] >>> 49);
+    buf[off++] = (byte) (values[4] >>> 41);
+    buf[off++] = (byte) (values[4] >>> 33);
+    buf[off++] = (byte) (values[4] >>> 25);
+    buf[off++] = (byte) (values[4] >>> 17);
+    buf[off++] = (byte) (values[4] >>> 9);
+    buf[off++] = (byte) (values[4] >>> 1);
+
+    buf[off] = (byte) (values[4] << 7);
+    buf[off++] |= values[5] >>> 54;
+    buf[off++] = (byte) (values[5] >>> 46);
+    buf[off++] = (byte) (values[5] >>> 38);
+    buf[off++] = (byte) (values[5] >>> 30);
+    buf[off++] = (byte) (values[5] >>> 22);
+    buf[off++] = (byte) (values[5] >>> 14);
+    buf[off++] = (byte) (values[5] >>> 6);
+
+    buf[off] = (byte) (values[5] << 2);
+    buf[off++] |= values[6] >>> 59;
+    buf[off++] = (byte) (values[6] >>> 51);
+    buf[off++] = (byte) (values[6] >>> 43);
+    buf[off++] = (byte) (values[6] >>> 35);
+    buf[off++] = (byte) (values[6] >>> 27);
+    buf[off++] = (byte) (values[6] >>> 19);
+    buf[off++] = (byte) (values[6] >>> 11);
+    buf[off++] = (byte) (values[6] >>> 3);
+
+    buf[off] = (byte) (values[6] << 5);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits62(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 54);
+    buf[off++] = (byte) (values[0] >>> 46);
+    buf[off++] = (byte) (values[0] >>> 38);
+    buf[off++] = (byte) (values[0] >>> 30);
+    buf[off++] = (byte) (values[0] >>> 22);
+    buf[off++] = (byte) (values[0] >>> 14);
+    buf[off++] = (byte) (values[0] >>> 6);
+
+    buf[off] = (byte) (values[0] << 2);
+    buf[off++] |= values[1] >>> 60;
+    buf[off++] = (byte) (values[1] >>> 52);
+    buf[off++] = (byte) (values[1] >>> 44);
+    buf[off++] = (byte) (values[1] >>> 36);
+    buf[off++] = (byte) (values[1] >>> 28);
+    buf[off++] = (byte) (values[1] >>> 20);
+    buf[off++] = (byte) (values[1] >>> 12);
+    buf[off++] = (byte) (values[1] >>> 4);
+
+    buf[off] = (byte) (values[1] << 4);
+    buf[off++] |= values[2] >>> 58;
+    buf[off++] = (byte) (values[2] >>> 50);
+    buf[off++] = (byte) (values[2] >>> 42);
+    buf[off++] = (byte) (values[2] >>> 34);
+    buf[off++] = (byte) (values[2] >>> 26);
+    buf[off++] = (byte) (values[2] >>> 18);
+    buf[off++] = (byte) (values[2] >>> 10);
+    buf[off++] = (byte) (values[2] >>> 2);
+
+    buf[off] = (byte) (values[2] << 6);
+    buf[off++] |= values[3] >>> 56;
+    buf[off++] = (byte) (values[3] >>> 48);
+    buf[off++] = (byte) (values[3] >>> 40);
+    buf[off++] = (byte) (values[3] >>> 32);
+    buf[off++] = (byte) (values[3] >>> 24);
+    buf[off++] = (byte) (values[3] >>> 16);
+    buf[off++] = (byte) (values[3] >>> 8);
+    buf[off++] = (byte) (values[3]);
+
+    buf[off++] = (byte) (values[4] >>> 54);
+    buf[off++] = (byte) (values[4] >>> 46);
+    buf[off++] = (byte) (values[4] >>> 38);
+    buf[off++] = (byte) (values[4] >>> 30);
+    buf[off++] = (byte) (values[4] >>> 22);
+    buf[off++] = (byte) (values[4] >>> 14);
+    buf[off++] = (byte) (values[4] >>> 6);
+
+    buf[off] = (byte) (values[4] << 2);
+    buf[off++] |= values[5] >>> 60;
+    buf[off++] = (byte) (values[5] >>> 52);
+    buf[off++] = (byte) (values[5] >>> 44);
+    buf[off++] = (byte) (values[5] >>> 36);
+    buf[off++] = (byte) (values[5] >>> 28);
+    buf[off++] = (byte) (values[5] >>> 20);
+    buf[off++] = (byte) (values[5] >>> 12);
+    buf[off++] = (byte) (values[5] >>> 4);
+
+    buf[off] = (byte) (values[5] << 4);
+    buf[off++] |= values[6] >>> 58;
+    buf[off++] = (byte) (values[6] >>> 50);
+    buf[off++] = (byte) (values[6] >>> 42);
+    buf[off++] = (byte) (values[6] >>> 34);
+    buf[off++] = (byte) (values[6] >>> 26);
+    buf[off++] = (byte) (values[6] >>> 18);
+    buf[off++] = (byte) (values[6] >>> 10);
+    buf[off++] = (byte) (values[6] >>> 2);
+
+    buf[off] = (byte) (values[6] << 6);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) (values[7]);
+  }
+
+  static void packBits63(long[] values, int i, byte[] buf, int off) {
+    buf[off++] = (byte) (values[0] >>> 55);
+    buf[off++] = (byte) (values[0] >>> 47);
+    buf[off++] = (byte) (values[0] >>> 39);
+    buf[off++] = (byte) (values[0] >>> 31);
+    buf[off++] = (byte) (values[0] >>> 23);
+    buf[off++] = (byte) (values[0] >>> 15);
+    buf[off++] = (byte) (values[0] >>> 7);
+
+    buf[off] = (byte) (values[0] << 1);
+    buf[off++] |= values[1] >>> 62;
+    buf[off++] = (byte) (values[1] >>> 54);
+    buf[off++] = (byte) (values[1] >>> 46);
+    buf[off++] = (byte) (values[1] >>> 38);
+    buf[off++] = (byte) (values[1] >>> 30);
+    buf[off++] = (byte) (values[1] >>> 22);
+    buf[off++] = (byte) (values[1] >>> 14);
+    buf[off++] = (byte) (values[1] >>> 6);
+
+    buf[off] = (byte) (values[1] << 2);
+    buf[off++] |= values[2] >>> 61;
+    buf[off++] = (byte) (values[2] >>> 53);
+    buf[off++] = (byte) (values[2] >>> 45);
+    buf[off++] = (byte) (values[2] >>> 37);
+    buf[off++] = (byte) (values[2] >>> 29);
+    buf[off++] = (byte) (values[2] >>> 21);
+    buf[off++] = (byte) (values[2] >>> 13);
+    buf[off++] = (byte) (values[2] >>> 5);
+
+    buf[off] = (byte) (values[2] << 3);
+    buf[off++] |= values[3] >>> 60;
+    buf[off++] = (byte) (values[3] >>> 52);
+    buf[off++] = (byte) (values[3] >>> 44);
+    buf[off++] = (byte) (values[3] >>> 36);
+    buf[off++] = (byte) (values[3] >>> 28);
+    buf[off++] = (byte) (values[3] >>> 20);
+    buf[off++] = (byte) (values[3] >>> 12);
+    buf[off++] = (byte) (values[3] >>> 4);
+
+    buf[off] = (byte) (values[3] << 4);
+    buf[off++] |= values[4] >>> 59;
+    buf[off++] = (byte) (values[4] >>> 51);
+    buf[off++] = (byte) (values[4] >>> 43);
+    buf[off++] = (byte) (values[4] >>> 35);
+    buf[off++] = (byte) (values[4] >>> 27);
+    buf[off++] = (byte) (values[4] >>> 19);
+    buf[off++] = (byte) (values[4] >>> 11);
+    buf[off++] = (byte) (values[4] >>> 3);
+
+    buf[off] = (byte) (values[4] << 5);
+    buf[off++] |= values[5] >>> 58;
+    buf[off++] = (byte) (values[5] >>> 50);
+    buf[off++] = (byte) (values[5] >>> 42);
+    buf[off++] = (byte) (values[5] >>> 34);
+    buf[off++] = (byte) (values[5] >>> 26);
+    buf[off++] = (byte) (values[5] >>> 18);
+    buf[off++] = (byte) (values[5] >>> 10);
+    buf[off++] = (byte) (values[5] >>> 2);
+
+    buf[off] = (byte) (values[5] << 6);
+    buf[off++] |= values[6] >>> 57;
+    buf[off++] = (byte) (values[6] >>> 49);
+    buf[off++] = (byte) (values[6] >>> 41);
+    buf[off++] = (byte) (values[6] >>> 33);
+    buf[off++] = (byte) (values[6] >>> 25);
+    buf[off++] = (byte) (values[6] >>> 17);
+    buf[off++] = (byte) (values[6] >>> 9);
+    buf[off++] = (byte) (values[6] >>> 1);
+
+    buf[off] = (byte) (values[6] << 7);
+    buf[off++] |= values[7] >>> 56;
+    buf[off++] = (byte) (values[7] >>> 48);
+    buf[off++] = (byte) (values[7] >>> 40);
+    buf[off++] = (byte) (values[7] >>> 32);
+    buf[off++] = (byte) (values[7] >>> 24);
+    buf[off++] = (byte) (values[7] >>> 16);
+    buf[off++] = (byte) (values[7] >>> 8);
+    buf[off] = (byte) values[7];
+  }
+
+  static void unpackBits1(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off]) >>> 7) & 1;
+    values[i + 1] = (Byte.toUnsignedLong(buf[off]) >>> 6) & 1;
+    values[i + 2] = (Byte.toUnsignedLong(buf[off]) >>> 5) & 1;
+    values[i + 3] = (Byte.toUnsignedLong(buf[off]) >>> 4) & 1;
+    values[i + 4] = (Byte.toUnsignedLong(buf[off]) >>> 3) & 1;
+    values[i + 5] = (Byte.toUnsignedLong(buf[off]) >>> 2) & 1;
+    values[i + 6] = (Byte.toUnsignedLong(buf[off]) >>> 1) & 1;
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 1;
+  }
+
+  static void unpackBits2(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off]) >>> 6) & 3;
+    values[i + 1] = (Byte.toUnsignedLong(buf[off]) >>> 4) & 3;
+    values[i + 2] = (Byte.toUnsignedLong(buf[off]) >>> 2) & 3;
+    values[i + 3] = Byte.toUnsignedLong(buf[off++]) & 3;
+    values[i + 4] = (Byte.toUnsignedLong(buf[off]) >>> 6) & 3;
+    values[i + 5] = (Byte.toUnsignedLong(buf[off]) >>> 4) & 3;
+    values[i + 6] = (Byte.toUnsignedLong(buf[off]) >>> 2) & 3;
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 3;
+  }
+
+  static void unpackBits3(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off]) >>> 5;
+    values[i + 1] = (Byte.toUnsignedLong(buf[off]) >>> 2) & 7;
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+    values[i + 3] = (Byte.toUnsignedLong(buf[off]) >>> 4) & 7;
+    values[i + 4] = (Byte.toUnsignedLong(buf[off]) >>> 1) & 7;
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+    values[i + 6] = (Byte.toUnsignedLong(buf[off]) >>> 3) & 7;
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 7;
+  }
+
+  static void unpackBits4(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off]) >>> 4;
+    values[i + 1] = Byte.toUnsignedLong(buf[off++]) & 0xf;
+    values[i + 2] = Byte.toUnsignedLong(buf[off]) >>> 4;
+    values[i + 3] = Byte.toUnsignedLong(buf[off++]) & 0xf;
+    values[i + 4] = Byte.toUnsignedLong(buf[off]) >>> 4;
+    values[i + 5] = Byte.toUnsignedLong(buf[off++]) & 0xf;
+    values[i + 6] = Byte.toUnsignedLong(buf[off]) >>> 4;
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 0xf;
+  }
+
+  static void unpackBits5(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off]) >>> 1) & 0x1f;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off]) >>> 2) & 0x1f;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 0x1f;
+  }
+
+  static void unpackBits6(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = Byte.toUnsignedLong(buf[off++]) & 0x3f;
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 0x3f;
+  }
+
+  static void unpackBits7(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = Byte.toUnsignedLong(buf[off]) & 0x7f;
+  }
+
+  static void unpackBits8(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits9(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits10(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits11(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits12(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits13(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits14(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits15(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits16(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits17(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 11;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 13;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 15;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits18(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 14;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 14;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits19(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 17;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 15;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 13;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits20(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits21(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 15;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 17;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 19;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits22(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 18;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 18;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits23(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 21;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 19;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 17;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits24(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits25(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 19;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 21;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 23;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits26(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 22;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 22;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits27(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 25;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 23;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 21;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits28(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits29(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 23;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 25;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 27;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits30(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 26;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 26;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits31(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 29;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 27;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 25;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits32(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits33(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 27;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 29;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 30;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 31;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 32;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits34(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 30;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 30;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]);
+  }
+
+  static void unpackBits35(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 2) << 33;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 31;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 29;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits36(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits37(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 31;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 23;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 33;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 30;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 35;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits38(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 34;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 34;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits39(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 37;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 35;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 33;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits40(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits41(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 35;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 37;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 38;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 39;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits42(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 38;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 38;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits43(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 41;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 39;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 42;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 37;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits44(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 40;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 40;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits45(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 42;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 39;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 23;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 41;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 38;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 43;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits46(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 44;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 42;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 44;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 42;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits47(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 46;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 45;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 43;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 42;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 41;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits48(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits49(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 42;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 43;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 45;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 46;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 47;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits50(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 44;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 46;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 44;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 46;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits51(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 46;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 49;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 47;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 50;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 45;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits52(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 48;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 48;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits53(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 45;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 50;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 47;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 23;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 52;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 49;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 46;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 51;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits54(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 52;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 50;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 52;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 50;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]);
+  }
+
+  static void unpackBits55(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 47;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 54;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 53;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 45;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 52;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 51;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 50;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 49;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits56(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]);
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits57(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 49;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 50;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 51;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 52;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 53;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 45;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 7) << 54;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 55;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 47;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 1) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits58(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 52;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 54;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 3) << 56;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 52;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 54;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 3) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]);
+  }
+
+  static void unpackBits59(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 51;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 54;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 57;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 49;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 52;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 55;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 47;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 1) << 58;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 53;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 45;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 7) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits60(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 56;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 56;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 56;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits61(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 53;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 45;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 7) << 58;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 55;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 47;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 1) << 60;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 57;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 49;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 54;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 3) << 59;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 51;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits62(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 54;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 3) << 60;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 58;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 56;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]);
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++])) << 54;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 3) << 60;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 58;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+  static void unpackBits63(long[] values, int i, byte[] buf, int off) {
+    values[i + 0] = (Byte.toUnsignedLong(buf[off++])) << 55;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 47;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 39;
+    values[i + 0] |= (Byte.toUnsignedLong(buf[off++])) << 31;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 23;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 15;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off++]) << 7;
+    values[i + 0] |= Byte.toUnsignedLong(buf[off]) >>> 1;
+
+    values[i + 1] = (Byte.toUnsignedLong(buf[off++]) & 1) << 62;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 54;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 46;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 38;
+    values[i + 1] |= (Byte.toUnsignedLong(buf[off++])) << 30;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 22;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 14;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off++]) << 6;
+    values[i + 1] |= Byte.toUnsignedLong(buf[off]) >>> 2;
+
+    values[i + 2] = (Byte.toUnsignedLong(buf[off++]) & 3) << 61;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 53;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 45;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 37;
+    values[i + 2] |= (Byte.toUnsignedLong(buf[off++])) << 29;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 21;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 13;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off++]) << 5;
+    values[i + 2] |= Byte.toUnsignedLong(buf[off]) >>> 3;
+
+    values[i + 3] = (Byte.toUnsignedLong(buf[off++]) & 7) << 60;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 52;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 44;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 36;
+    values[i + 3] |= (Byte.toUnsignedLong(buf[off++])) << 28;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 20;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 12;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off++]) << 4;
+    values[i + 3] |= Byte.toUnsignedLong(buf[off]) >>> 4;
+
+    values[i + 4] = (Byte.toUnsignedLong(buf[off++]) & 0xf) << 59;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 51;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 43;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 35;
+    values[i + 4] |= (Byte.toUnsignedLong(buf[off++])) << 27;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 19;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 11;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off++]) << 3;
+    values[i + 4] |= Byte.toUnsignedLong(buf[off]) >>> 5;
+
+    values[i + 5] = (Byte.toUnsignedLong(buf[off++]) & 0x1f) << 58;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 50;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 42;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 34;
+    values[i + 5] |= (Byte.toUnsignedLong(buf[off++])) << 26;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 18;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 10;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off++]) << 2;
+    values[i + 5] |= Byte.toUnsignedLong(buf[off]) >>> 6;
+
+    values[i + 6] = (Byte.toUnsignedLong(buf[off++]) & 0x3f) << 57;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 49;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 41;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 33;
+    values[i + 6] |= (Byte.toUnsignedLong(buf[off++])) << 25;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 17;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 9;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off++]) << 1;
+    values[i + 6] |= Byte.toUnsignedLong(buf[off]) >>> 7;
+
+    values[i + 7] = (Byte.toUnsignedLong(buf[off++]) & 0x7f) << 56;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 48;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 40;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 32;
+    values[i + 7] |= (Byte.toUnsignedLong(buf[off++])) << 24;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 16;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off++]) << 8;
+    values[i + 7] |= Byte.toUnsignedLong(buf[off]);
+  }
+
+}
diff --git a/src/main/java/org/apache/datasketches/theta/CompactSketch.java b/src/main/java/org/apache/datasketches/theta/CompactSketch.java
index 82f1f1c0..292063aa 100644
--- a/src/main/java/org/apache/datasketches/theta/CompactSketch.java
+++ b/src/main/java/org/apache/datasketches/theta/CompactSketch.java
@@ -22,12 +22,16 @@ package org.apache.datasketches.theta;
 import static org.apache.datasketches.common.Family.idToFamily;
 import static org.apache.datasketches.theta.PreambleUtil.COMPACT_FLAG_MASK;
 import static org.apache.datasketches.theta.PreambleUtil.EMPTY_FLAG_MASK;
-import static org.apache.datasketches.theta.PreambleUtil.FAMILY_BYTE;
-import static org.apache.datasketches.theta.PreambleUtil.FLAGS_BYTE;
 import static org.apache.datasketches.theta.PreambleUtil.ORDERED_FLAG_MASK;
 import static org.apache.datasketches.theta.PreambleUtil.READ_ONLY_FLAG_MASK;
-import static org.apache.datasketches.theta.PreambleUtil.SER_VER_BYTE;
+import static org.apache.datasketches.theta.PreambleUtil.extractFamilyID;
+import static org.apache.datasketches.theta.PreambleUtil.extractFlags;
+import static org.apache.datasketches.theta.PreambleUtil.extractPreLongs;
 import static org.apache.datasketches.theta.PreambleUtil.extractSeedHash;
+import static org.apache.datasketches.theta.PreambleUtil.extractSerVer;
+import static org.apache.datasketches.theta.PreambleUtil.extractEntryBitsV4;
+import static org.apache.datasketches.theta.PreambleUtil.extractNumEntriesBytesV4;
+import static org.apache.datasketches.theta.PreambleUtil.extractThetaLongV4;
 import static org.apache.datasketches.theta.SingleItemSketch.otherCheckForSingleItem;
 
 import org.apache.datasketches.common.Family;
@@ -50,7 +54,6 @@ import org.apache.datasketches.thetacommon.ThetaUtil;
  * @author Lee Rhodes
  */
 public abstract class CompactSketch extends Sketch {
-  private static final short defaultSeedHash = ThetaUtil.computeSeedHash(ThetaUtil.DEFAULT_UPDATE_SEED);
 
   /**
    * Heapify takes a CompactSketch image in Memory and instantiates an on-heap CompactSketch.
@@ -68,26 +71,7 @@ public abstract class CompactSketch extends Sketch {
    * @return a CompactSketch on the heap.
    */
   public static CompactSketch heapify(final Memory srcMem) {
-    final int serVer = srcMem.getByte(SER_VER_BYTE) & 0XFF;
-    final int familyID = srcMem.getByte(FAMILY_BYTE) & 0XFF;
-    final Family family = Family.idToFamily(familyID);
-    if (family != Family.COMPACT) {
-      throw new IllegalArgumentException("Corrupted: " + family + " is not Compact!");
-    }
-    if (serVer == 3) { //no seed check
-      final int flags = PreambleUtil.extractFlags(srcMem);
-      final boolean srcOrdered = (flags & ORDERED_FLAG_MASK) != 0;
-      return CompactOperations.memoryToCompact(srcMem, srcOrdered, null);
-    }
-    //not SerVer 3, assume compact stored form
-    if (serVer == 1) {
-      return ForwardCompatibility.heapify1to3(srcMem, defaultSeedHash);
-    }
-    if (serVer == 2) {
-      final short srcSeedHash = (short) extractSeedHash(srcMem);
-      return ForwardCompatibility.heapify2to3(srcMem, srcSeedHash);
-    }
-    throw new SketchesArgumentException("Unknown Serialization Version: " + serVer);
+    return heapify(srcMem, ThetaUtil.DEFAULT_UPDATE_SEED, false);
   }
 
   /**
@@ -107,27 +91,34 @@ public abstract class CompactSketch extends Sketch {
    * @return a CompactSketch on the heap.
    */
   public static CompactSketch heapify(final Memory srcMem, final long expectedSeed) {
-    final int serVer = srcMem.getByte(SER_VER_BYTE);
-    final byte familyID = srcMem.getByte(FAMILY_BYTE);
+    return heapify(srcMem, expectedSeed, true);
+  }
 
+  private static CompactSketch heapify(final Memory srcMem, final long seed, final boolean enforceSeed) {
+    final int serVer = extractSerVer(srcMem);
+    final int familyID = extractFamilyID(srcMem);
     final Family family = idToFamily(familyID);
     if (family != Family.COMPACT) {
       throw new IllegalArgumentException("Corrupted: " + family + " is not Compact!");
     }
+    if (serVer == 4) {
+       return heapifyV4(srcMem, seed, enforceSeed);
+    }
     if (serVer == 3) {
-      final int flags = PreambleUtil.extractFlags(srcMem);
+      final int flags = extractFlags(srcMem);
       final boolean srcOrdered = (flags & ORDERED_FLAG_MASK) != 0;
       final boolean empty = (flags & EMPTY_FLAG_MASK) != 0;
-      if (!empty) { PreambleUtil.checkMemorySeedHash(srcMem, expectedSeed); }
+      if (enforceSeed && !empty) { PreambleUtil.checkMemorySeedHash(srcMem, seed); }
       return CompactOperations.memoryToCompact(srcMem, srcOrdered, null);
     }
     //not SerVer 3, assume compact stored form
-    final short seedHash = ThetaUtil.computeSeedHash(expectedSeed);
+    final short seedHash = ThetaUtil.computeSeedHash(seed);
     if (serVer == 1) {
       return ForwardCompatibility.heapify1to3(srcMem, seedHash);
     }
     if (serVer == 2) {
-      return ForwardCompatibility.heapify2to3(srcMem, seedHash);
+      return ForwardCompatibility.heapify2to3(srcMem,
+          enforceSeed ? seedHash : (short) extractSeedHash(srcMem));
     }
     throw new SketchesArgumentException("Unknown Serialization Version: " + serVer);
   }
@@ -155,43 +146,7 @@ public abstract class CompactSketch extends Sketch {
    * @return a CompactSketch backed by the given Memory except as above.
    */
   public static CompactSketch wrap(final Memory srcMem) {
-    final int serVer = srcMem.getByte(SER_VER_BYTE) & 0XFF;
-    final int familyID = srcMem.getByte(FAMILY_BYTE) & 0XFF;
-    final Family family = Family.idToFamily(familyID);
-    if (family != Family.COMPACT) {
-      throw new IllegalArgumentException("Corrupted: " + family + " is not Compact!");
-    }
-    if (serVer == 3) {
-      if (PreambleUtil.isEmptyFlag(srcMem)) {
-        return EmptyCompactSketch.getHeapInstance(srcMem);
-      }
-      final short memSeedHash = (short) extractSeedHash(srcMem);
-      if (otherCheckForSingleItem(srcMem)) { //SINGLEITEM?
-        return SingleItemSketch.heapify(srcMem, memSeedHash);
-      }
-      //not empty & not singleItem
-      final int flags = srcMem.getByte(FLAGS_BYTE);
-      final boolean compactFlag = (flags & COMPACT_FLAG_MASK) > 0;
-      if (!compactFlag) {
-        throw new SketchesArgumentException(
-            "Corrupted: COMPACT family sketch image must have compact flag set");
-      }
-      final boolean readOnly = (flags & READ_ONLY_FLAG_MASK) > 0;
-      if (!readOnly) {
-        throw new SketchesArgumentException(
-            "Corrupted: COMPACT family sketch image must have Read-Only flag set");
-      }
-      return DirectCompactSketch.wrapInstance(srcMem, memSeedHash);
-    } //end of serVer 3
-    else if (serVer == 1) {
-      return ForwardCompatibility.heapify1to3(srcMem, defaultSeedHash);
-    }
-    else if (serVer == 2) {
-      final short memSeedHash = (short) extractSeedHash(srcMem);
-      return ForwardCompatibility.heapify2to3(srcMem, memSeedHash);
-    }
-    throw new SketchesArgumentException(
-        "Corrupted: Serialization Version " + serVer + " not recognized.");
+    return wrap(srcMem, ThetaUtil.DEFAULT_UPDATE_SEED, false);
   }
 
   /**
@@ -219,23 +174,32 @@ public abstract class CompactSketch extends Sketch {
    * @return a CompactSketch backed by the given Memory except as above.
    */
   public static CompactSketch wrap(final Memory srcMem, final long expectedSeed) {
-    final int serVer = srcMem.getByte(SER_VER_BYTE) & 0XFF;
-    final int familyID = srcMem.getByte(FAMILY_BYTE) & 0XFF;
+    return wrap(srcMem, expectedSeed, true);
+  }
+
+  private static CompactSketch wrap(final Memory srcMem, final long seed, final boolean enforceSeed) {
+    final int serVer = extractSerVer(srcMem);
+    final int familyID = extractFamilyID(srcMem);
     final Family family = Family.idToFamily(familyID);
     if (family != Family.COMPACT) {
       throw new IllegalArgumentException("Corrupted: " + family + " is not Compact!");
     }
-    final short seedHash = ThetaUtil.computeSeedHash(expectedSeed);
+    final short seedHash = ThetaUtil.computeSeedHash(seed);
 
-    if (serVer == 3) {
+    if (serVer == 4) {
+      // not wrapping the compressed format since currently we cannot take advantage of
+      // decompression during iteration because set operations reach into memory directly
+      return heapifyV4(srcMem, seed, enforceSeed);
+    }
+    else if (serVer == 3) {
       if (PreambleUtil.isEmptyFlag(srcMem)) {
         return EmptyCompactSketch.getHeapInstance(srcMem);
       }
-      if (otherCheckForSingleItem(srcMem)) { //SINGLEITEM?
-        return SingleItemSketch.heapify(srcMem, seedHash);
+      if (otherCheckForSingleItem(srcMem)) {
+        return SingleItemSketch.heapify(srcMem, enforceSeed ? seedHash : (short) extractSeedHash(srcMem));
       }
       //not empty & not singleItem
-      final int flags = srcMem.getByte(FLAGS_BYTE);
+      final int flags = extractFlags(srcMem);
       final boolean compactFlag = (flags & COMPACT_FLAG_MASK) > 0;
       if (!compactFlag) {
         throw new SketchesArgumentException(
@@ -246,20 +210,20 @@ public abstract class CompactSketch extends Sketch {
         throw new SketchesArgumentException(
             "Corrupted: COMPACT family sketch image must have Read-Only flag set");
       }
-      return DirectCompactSketch.wrapInstance(srcMem, seedHash);
+      return DirectCompactSketch.wrapInstance(srcMem,
+          enforceSeed ? seedHash : (short) extractSeedHash(srcMem));
     } //end of serVer 3
     else if (serVer == 1) {
       return ForwardCompatibility.heapify1to3(srcMem, seedHash);
     }
     else if (serVer == 2) {
-      return ForwardCompatibility.heapify2to3(srcMem, seedHash);
+      return ForwardCompatibility.heapify2to3(srcMem,
+          enforceSeed ? seedHash : (short) extractSeedHash(srcMem));
     }
     throw new SketchesArgumentException(
         "Corrupted: Serialization Version " + serVer + " not recognized.");
-
   }
 
-
   //Sketch Overrides
 
   @Override
@@ -285,4 +249,128 @@ public abstract class CompactSketch extends Sketch {
     return true;
   }
 
+  public byte[] toByteArrayCompressed() {
+    if (!isOrdered() || getRetainedEntries() == 0 || (getRetainedEntries() == 1 && !isEstimationMode())) {
+      return toByteArray();
+    }
+    return toByteArrayV4();
+  }
+
+  private int computeMinLeadingZeros() {
+    // compression is based on leading zeros in deltas between ordered hash values
+    // assumes ordered sketch
+    long previous = 0;
+    long ored = 0;
+    HashIterator it = iterator();
+    while (it.next()) {
+      final long delta = it.get() - previous;
+      ored |= delta;
+      previous = it.get();
+    }
+    return Long.numberOfLeadingZeros(ored);
+  }
+
+  private static int wholeBytesToHoldBits(int bits) {
+    return (bits >>> 3) + ((bits & 7) > 0 ? 1 : 0);
+  }
+
+  private byte[] toByteArrayV4() {
+    final int preambleLongs = isEstimationMode() ? 2 : 1;
+    final int entryBits = 64 - computeMinLeadingZeros();
+    final int compressedBits = entryBits * getRetainedEntries();
+
+    // store num_entries as whole bytes since whole-byte blocks will follow (most probably)
+    final int numEntriesBytes = wholeBytesToHoldBits(32 - Integer.numberOfLeadingZeros(getRetainedEntries()));
+
+    final int size = preambleLongs * Long.BYTES + numEntriesBytes + wholeBytesToHoldBits(compressedBits);
+    final byte[] bytes = new byte[size];
+    final WritableMemory mem = WritableMemory.writableWrap(bytes);
+    int offsetBytes = 0;
+    mem.putByte(offsetBytes++, (byte) preambleLongs);
+    mem.putByte(offsetBytes++, (byte) 4); // to do: add constant
+    mem.putByte(offsetBytes++, (byte) Family.COMPACT.getID());
+    mem.putByte(offsetBytes++, (byte) entryBits);
+    mem.putByte(offsetBytes++, (byte) numEntriesBytes);
+    mem.putByte(offsetBytes++, (byte) (COMPACT_FLAG_MASK | READ_ONLY_FLAG_MASK | ORDERED_FLAG_MASK));
+    mem.putShort(offsetBytes, getSeedHash());
+    offsetBytes += Short.BYTES;
+    if (isEstimationMode()) {
+      mem.putLong(offsetBytes, getThetaLong());
+      offsetBytes += Long.BYTES;
+    }
+    int numEntries = getRetainedEntries();
+    for (int i = 0; i < numEntriesBytes; i++) {
+      mem.putByte(offsetBytes++, (byte) (numEntries & 0xff));
+      numEntries >>>= 8;
+    }
+    long previous = 0;
+    long[] deltas = new long[8];
+    HashIterator it = iterator();
+    int i;
+    for (i = 0; i + 7 < getRetainedEntries(); i += 8) {
+      for (int j = 0; j < 8; j++) {
+        it.next();
+        deltas[j] = it.get() - previous;
+        previous = it.get();
+      }
+      BitPacking.packBitsBlock8(deltas, 0, bytes, offsetBytes, entryBits);
+      offsetBytes += entryBits;
+    }
+    int offsetBits = 0;
+    for (; i < getRetainedEntries(); i++) {
+      it.next();
+      final long delta = it.get() - previous;
+      previous = it.get();
+      BitPacking.packBits(delta, entryBits, bytes, offsetBytes, offsetBits);
+      offsetBytes += (offsetBits + entryBits) >>> 3;
+      offsetBits = (offsetBits + entryBits) & 7;
+    }
+    return bytes;
+  }
+
+  private static CompactSketch heapifyV4(final Memory srcMem, final long seed, final boolean enforceSeed) {
+    final int preLongs = extractPreLongs(srcMem);
+    final int flags = extractFlags(srcMem);
+    final int entryBits = extractEntryBitsV4(srcMem);
+    final int numEntriesBytes = extractNumEntriesBytesV4(srcMem);
+    final short seedHash = (short) extractSeedHash(srcMem);
+    final boolean isEmpty = (flags & EMPTY_FLAG_MASK) > 0;
+    if (enforceSeed && !isEmpty) { PreambleUtil.checkMemorySeedHash(srcMem, seed); }
+    int offsetBytes = 8;
+    long theta = Long.MAX_VALUE;
+    if (preLongs > 1) {
+      theta = extractThetaLongV4(srcMem);
+      offsetBytes += Long.BYTES;
+    }
+    int numEntries = 0;
+    for (int i = 0; i < numEntriesBytes; i++) {
+      numEntries |= Byte.toUnsignedInt(srcMem.getByte(offsetBytes++)) << (i << 3);
+    }
+    final long[] entries = new long[numEntries];
+    final byte[] bytes = new byte[entryBits]; // temporary buffer for unpacking
+    int i;
+    for (i = 0; i + 7 < numEntries; i += 8) {
+      srcMem.getByteArray(offsetBytes, bytes, 0, entryBits);
+      BitPacking.unpackBitsBlock8(entries, i, bytes, 0, entryBits);
+      offsetBytes += entryBits;
+    }
+    if (i < numEntries) {
+      srcMem.getByteArray(offsetBytes, bytes, 0, wholeBytesToHoldBits((numEntries - i) * entryBits));
+      int offsetBits = 0;
+      offsetBytes = 0;
+      for (; i < numEntries; i++) {
+        BitPacking.unpackBits(entries, i, entryBits, bytes, offsetBytes, offsetBits);
+        offsetBytes += (offsetBits + entryBits) >>> 3;
+        offsetBits = (offsetBits + entryBits) & 7;
+      }
+    }
+    // undo deltas
+    long previous = 0;
+    for (i = 0; i < numEntries; i++) {
+      entries[i] += previous;
+      previous = entries[i];
+    }
+    return new HeapCompactSketch(entries, isEmpty, seedHash, numEntries, theta, true);
+  }
+
 }
diff --git a/src/main/java/org/apache/datasketches/theta/PreambleUtil.java b/src/main/java/org/apache/datasketches/theta/PreambleUtil.java
index 50a70558..3c34b356 100644
--- a/src/main/java/org/apache/datasketches/theta/PreambleUtil.java
+++ b/src/main/java/org/apache/datasketches/theta/PreambleUtil.java
@@ -188,6 +188,11 @@ final class PreambleUtil {
   //Other constants
   static final int SER_VER                    = 3;
 
+  // serial version 4 compressed ordered sketch, not empty, not single item
+  static final int ENTRY_BITS_BYTE_V4   = 3; // number of bits packed in deltas between hashes
+  static final int NUM_ENTRIES_BYTES_BYTE_V4 = 4; // number of bytes used for the number of entries
+  static final int THETA_LONG_V4             = 8; //8-byte aligned
+
   static final boolean NATIVE_ORDER_IS_BIG_ENDIAN  =
       (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN);
 
@@ -397,6 +402,18 @@ final class PreambleUtil {
     return mem.getLong(UNION_THETA_LONG);
   }
 
+  static int extractEntryBitsV4(final Memory mem) {
+    return mem.getByte(ENTRY_BITS_BYTE_V4) & 0XFF;
+  }
+
+  static int extractNumEntriesBytesV4(final Memory mem) {
+    return mem.getByte(NUM_ENTRIES_BYTES_BYTE_V4) & 0XFF;
+  }
+
+  static long extractThetaLongV4(final Memory mem) {
+    return mem.getLong(THETA_LONG);
+  }
+
   /**
    * Sets PreLongs in the low 6 bits and sets LgRF in the upper 2 bits = 0.
    * @param wmem the target WritableMemory
diff --git a/src/main/java/org/apache/datasketches/theta/UnionImpl.java b/src/main/java/org/apache/datasketches/theta/UnionImpl.java
index 4da32745..08cb3fe4 100644
--- a/src/main/java/org/apache/datasketches/theta/UnionImpl.java
+++ b/src/main/java/org/apache/datasketches/theta/UnionImpl.java
@@ -297,7 +297,7 @@ final class UnionImpl extends Union {
   }
 
   @Override
-  public void union(final Sketch sketchIn) { //Only valid for theta Sketches using SerVer = 3
+  public void union(final Sketch sketchIn) { //Only valid for theta Sketches using SerVer >= 3
     //UNION Empty Rule: AND the empty states.
 
     if (sketchIn == null || sketchIn.isEmpty()) {
@@ -364,6 +364,14 @@ final class UnionImpl extends Union {
     final int serVer = extractSerVer(skMem);
     final int fam = extractFamilyID(skMem);
 
+    if (serVer == 4) { // compressed ordered compact
+      // performance can be improved by decompression while performing the union
+      // potentially only partial decompression might be needed
+      ThetaUtil.checkSeedHashes(expectedSeedHash_, (short) extractSeedHash(skMem));
+      final CompactSketch csk = CompactSketch.wrap(skMem);
+      union(csk);
+      return;
+    }
     if (serVer == 3) { //The OpenSource sketches (Aug 4, 2015) starts with serVer = 3
       if (fam < 1 || fam > 3) {
         throw new SketchesArgumentException(
@@ -372,14 +380,12 @@ final class UnionImpl extends Union {
       processVer3(skMem);
       return;
     }
-
     if (serVer == 2) { //older Sketch, which is compact and ordered
       ThetaUtil.checkSeedHashes(expectedSeedHash_, (short)extractSeedHash(skMem));
-      final CompactSketch csk = ForwardCompatibility.heapify2to3(skMem,expectedSeedHash_);
+      final CompactSketch csk = ForwardCompatibility.heapify2to3(skMem, expectedSeedHash_);
       union(csk);
       return;
     }
-
     if (serVer == 1) { //much older Sketch, which is compact and ordered, no seedHash
       final CompactSketch csk = ForwardCompatibility.heapify1to3(skMem, expectedSeedHash_);
       union(csk);
diff --git a/src/test/java/org/apache/datasketches/theta/BitPackingTest.java b/src/test/java/org/apache/datasketches/theta/BitPackingTest.java
new file mode 100644
index 00000000..9da9e7be
--- /dev/null
+++ b/src/test/java/org/apache/datasketches/theta/BitPackingTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.theta;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.datasketches.common.Util;
+import org.testng.annotations.Test;
+
+public class BitPackingTest {
+
+//for every number of bits from 1 to 63
+//generate pseudo-random data, pack, unpack and compare
+
+  @Test
+  public void packUnpackBits() {
+    for (int bits = 1; bits <= 63; bits++) {
+      final long mask = (1 << bits) - 1;
+      long[] input = new long[8];
+      final long golden64 = Util.iGoldenU64;
+      long value = 0xaa55aa55aa55aa55L; // arbitrary starting value
+      for (int i = 0; i < 8; ++i) {
+        input[i] = value & mask;
+        value += golden64;
+      }
+      byte[] bytes = new byte[8 * Long.BYTES];
+      int bitOffset = 0;
+      int bufOffset = 0;
+      for (int i = 0; i < 8; ++i) {
+        BitPacking.packBits(input[i], bits, bytes, bufOffset, bitOffset);
+        bufOffset += (bitOffset + bits) >>> 3;
+        bitOffset = (bitOffset + bits) & 7;
+      }
+
+      long[] output = new long[8];
+      bitOffset = 0;
+      bufOffset = 0;
+      for (int i = 0; i < 8; ++i) {
+        BitPacking.unpackBits(output, i, bits, bytes, bufOffset, bitOffset);
+        bufOffset += (bitOffset + bits) >>> 3;
+        bitOffset = (bitOffset + bits) & 7;
+      }
+      for (int i = 0; i < 8; ++i) {
+        assertEquals(output[i], input[i]);
+      }
+    }
+  }
+
+  @Test
+  public void packUnpackBlocks() {
+    for (int bits = 1; bits <= 63; bits++) {
+      System.out.println("bits " + bits);
+      final long mask = (1L << bits) - 1;
+      long[] input = new long[8];
+      final long golden64 = Util.iGoldenU64;
+      long value = 0xaa55aa55aa55aa55L; // arbitrary starting value
+      for (int i = 0; i < 8; ++i) {
+        input[i] = value & mask;
+        value += golden64;
+      }
+      byte[] bytes = new byte[8 * Long.BYTES];
+      BitPacking.packBitsBlock8(input, 0, bytes, 0, bits);
+      hexDump(bytes);
+
+      long[] output = new long[8];
+      BitPacking.unpackBitsBlock8(output, 0, bytes, 0, bits);
+
+      for (int i = 0; i < 8; ++i) {
+        System.out.println("checking value " + i);
+        assertEquals(output[i], input[i]);
+      }
+    }
+  }
+
+  void hexDump(byte[] bytes) {
+    for (int i = 0; i < bytes.length; i++) {
+      System.out.print(String.format("%02x ", bytes[i]));
+    }
+    System.out.println();
+  }
+
+}
diff --git a/src/test/java/org/apache/datasketches/theta/CompactSketchTest.java b/src/test/java/org/apache/datasketches/theta/CompactSketchTest.java
index 00ce964f..6bedbf43 100644
--- a/src/test/java/org/apache/datasketches/theta/CompactSketchTest.java
+++ b/src/test/java/org/apache/datasketches/theta/CompactSketchTest.java
@@ -406,6 +406,40 @@ public class CompactSketchTest {
     assertEquals(csk2.getCompactBytes(), 24 + (curCount * 8));
   }
 
+  @Test
+  public void serializeDeserializeHeapV4() {
+    UpdateSketch sk = Sketches.updateSketchBuilder().build();
+    for (int i = 0; i < 10000; i++) {
+      sk.update(i);
+    }
+    CompactSketch cs1 = sk.compact();
+    byte[] bytes = cs1.toByteArrayCompressed();
+    CompactSketch cs2 = CompactSketch.heapify(Memory.wrap(bytes));
+    assertEquals(cs1.getRetainedEntries(), cs2.getRetainedEntries());
+    HashIterator it1 = cs1.iterator();
+    HashIterator it2 = cs2.iterator();
+    while (it1.next() && it2.next()) {
+      assertEquals(it2.get(), it2.get());
+    }
+  }
+
+  @Test
+  public void serializeDeserializeDirectV4() {
+    UpdateSketch sk = Sketches.updateSketchBuilder().build();
+    for (int i = 0; i < 10000; i++) {
+      sk.update(i);
+    }
+    CompactSketch cs1 = sk.compact(true, WritableMemory.allocate(sk.getCompactBytes()));
+    byte[] bytes = cs1.toByteArrayCompressed();
+    CompactSketch cs2 = CompactSketch.wrap(Memory.wrap(bytes));
+    assertEquals(cs1.getRetainedEntries(), cs2.getRetainedEntries());
+    HashIterator it1 = cs1.iterator();
+    HashIterator it2 = cs2.iterator();
+    while (it1.next() && it2.next()) {
+      assertEquals(it2.get(), it2.get());
+    }
+  }
+
   private static class State {
     String classType = null;
     int count = 0;
diff --git a/src/test/java/org/apache/datasketches/theta/UnionImplTest.java b/src/test/java/org/apache/datasketches/theta/UnionImplTest.java
index db505bb0..4a3de896 100644
--- a/src/test/java/org/apache/datasketches/theta/UnionImplTest.java
+++ b/src/test/java/org/apache/datasketches/theta/UnionImplTest.java
@@ -97,6 +97,23 @@ public class UnionImplTest {
     assertEquals(union.getResult().getEstimate(), k, 0.0);
   }
 
+  @Test
+  public void checkUpdateWithMemV4Exact() {
+    int n = 1000;
+    UpdateSketch sk = Sketches.updateSketchBuilder().build();
+    for (int i = 0; i < n; i++) {
+      sk.update(i);
+    }
+    CompactSketch cs = sk.compact();
+    assertFalse(cs.isEstimationMode());
+
+    byte[] bytes = cs.toByteArrayCompressed();
+
+    final Union union = Sketches.setOperationBuilder().buildUnion();
+    union.union(Memory.wrap(bytes));
+    assertEquals(union.getResult().getEstimate(), n, 0.0);
+  }
+
   @Test
   public void checkFastWrap() {
     final int k = 16;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org