Index: lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java
===================================================================
--- lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java	(revision 1351317)
+++ lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java	(working copy)
@@ -1,6 +1,6 @@
 package org.apache.lucene.codecs.mockrandom;
 
-/*
+/**
  * 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.
@@ -61,6 +61,7 @@
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util._TestUtil;
+import org.apache.lucene.codecs.pfor.*;
 
 /**
  * Randomly combines terms index impl w/ postings impls.
@@ -93,6 +94,7 @@
       final int baseBlockSize = _TestUtil.nextInt(random, 1, 127);
       delegates.add(new MockVariableIntBlockPostingsFormat.MockIntFactory(baseBlockSize));
       // TODO: others
+      delegates.add(new PForFactory());
     }
 
     private static String getExtension(String fileName) {
Index: lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java
===================================================================
--- lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java	(revision 1351317)
+++ lucene/test-framework/src/java/org/apache/lucene/analysis/BaseTokenStreamTestCase.java	(working copy)
@@ -482,6 +482,7 @@
     add("MockVariableIntBlock");
     add("MockSep");
     add("MockRandom");
+    add("PFor");
   }};
   
   private static void checkRandomData(Random random, Analyzer a, int iterations, int maxWordLength, boolean useCharFilter, boolean simple, boolean offsetsAreCorrect, RandomIndexWriter iw) throws IOException {
Index: lucene/core/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat
===================================================================
--- lucene/core/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat	(revision 1351317)
+++ lucene/core/src/resources/META-INF/services/org.apache.lucene.codecs.PostingsFormat	(working copy)
@@ -17,3 +17,4 @@
 org.apache.lucene.codecs.pulsing.Pulsing40PostingsFormat
 org.apache.lucene.codecs.simpletext.SimpleTextPostingsFormat
 org.apache.lucene.codecs.memory.MemoryPostingsFormat
+org.apache.lucene.codecs.pfor.PForPostingsFormat
Index: lucene/core/src/test/org/apache/lucene/codecs/pfor/TestPForUtil.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/codecs/pfor/TestPForUtil.java	(revision 0)
+++ lucene/core/src/test/org/apache/lucene/codecs/pfor/TestPForUtil.java	(working copy)
@@ -0,0 +1,162 @@
+package org.apache.lucene;
+
+/**
+ * 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.
+ */
+
+import java.util.*;
+import java.io.*;
+import java.nio.*;
+import org.apache.lucene.codecs.pfor.*;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestPForUtil extends LuceneTestCase {
+  static final int[] MASK={ 0x00000000,
+    0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f,
+    0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
+    0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff,
+    0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
+    0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff,
+    0x7fffffff, 0xffffffff};
+  Random gen;
+  long seed=System.currentTimeMillis();
+  //long seed=1338528171959L;
+  public void initRandom() {
+  //  println("Seed: "+seed);
+    this.gen = new Random(seed);
+  }
+  public void testCompress() throws Exception {
+    initRandom();
+    tryForcedException();
+    tryAllDistribution();
+  }
+
+  // Test correctness of ignored forced exception
+  public void tryForcedException() throws Exception {
+    int sz=128;
+    Integer[] buff= new Integer[sz];
+    int[] data = new int[sz];
+    int[] copy = new int[sz];
+    byte[] res = new byte[4+sz*8];
+    IntBuffer resBuffer = ByteBuffer.wrap(res).asIntBuffer();
+    for (int i=0; i<sz-1; ++i)
+      buff[i]=gen.nextInt() & 0;
+    buff[sz-1]=gen.nextInt() & 0xffffffff;   // create only one exception
+
+    Collections.shuffle(Arrays.asList(buff),new Random(seed));
+    for (int i=0; i<sz; ++i)
+      data[i] = buff[i];
+
+    int ensz = PForUtil.compress(data,sz,resBuffer);
+
+    if (ensz > sz*8+4) {
+      println("Excceed? "+ensz+">"+(sz*8+4));
+      ensz=sz*8+4;
+    }
+    resBuffer.rewind();
+    PForUtil.decompress(resBuffer,copy);
+
+    //println(getHex(data,sz)+"\n");
+    //println(getHex(res,ensz)+"\n");
+    //println(getHex(copy,sz)+"\n");
+    
+    assert cmp(data,sz,copy,sz)==true;
+  }
+
+  // Test correctness of compressing and decompressing
+  public void tryAllDistribution() throws Exception {
+    for (int i=0; i<=32; ++i) { // try to test every kinds of distribution
+      double alpha=gen.nextDouble(); // rate of normal value
+      for (int j=0; j<=32; ++j) {
+        tryDistribution(128,alpha,MASK[i],MASK[j]);
+      }
+    }
+  }
+  public void tryDistribution(int sz, double alpha, int masknorm, int maskexc) throws Exception {
+    Integer[] buff= new Integer[sz];
+    int[] data = new int[sz];
+    byte[] res = new byte[4+sz*8];      // loosely upperbound
+    IntBuffer resBuffer = ByteBuffer.wrap(res).asIntBuffer();
+    int i=0;
+    for (; i<sz*alpha; ++i)
+      buff[i]=gen.nextInt() & masknorm;
+    for (; i<sz; ++i)
+      buff[i]=gen.nextInt() & maskexc;
+    Collections.shuffle(Arrays.asList(buff),new Random(seed));
+    for (i=0; i<sz; ++i)
+      data[i] = buff[i];
+
+    int ensz = PForUtil.compress(data,sz,resBuffer);
+    
+    if (ensz > sz*8+4) {
+      println("Excceed? "+ensz+">"+(sz*8+4));
+      ensz=sz*8+4;
+    }
+    int[] copy = new int[sz];
+    PForUtil.decompress(resBuffer,copy);
+
+//    println(getHex(data,sz)+"\n");
+//    println(getHex(res,ensz)+"\n");
+//    println(getHex(copy,sz)+"\n");
+
+    assert cmp(data,sz,copy,sz)==true;
+  }
+  public boolean cmp(int[] a, int sza, int[] b, int szb) {
+    if (sza!=szb)
+      return false;
+    for (int i=0; i<sza; ++i) {
+      if (a[i]!=b[i]) {
+        System.err.println(String.format("! %08x != %08x in %d",a[i],b[i],i));
+        return false;
+      }
+    }
+    return true;
+  }
+  public static String getHex( byte [] raw, int sz ) {
+    final String HEXES = "0123456789ABCDEF";
+    if ( raw == null ) {
+      return null;
+    }
+    final StringBuilder hex = new StringBuilder( 2 * raw.length );
+    for ( int i=0; i<sz; i++ ) {
+      if (i>0 && (i)%16 == 0)
+        hex.append("\n");
+      byte b=raw[i];
+      hex.append(HEXES.charAt((b & 0xF0) >> 4))
+         .append(HEXES.charAt((b & 0x0F)))
+         .append(" ");
+    }
+    return hex.toString();
+  }
+  public static String getHex( int [] raw, int sz ) {
+    if ( raw == null ) {
+      return null;
+    }
+    final StringBuilder hex = new StringBuilder( 4 * raw.length );
+    for ( int i=0; i<sz; i++ ) {
+      if (i>0 && i%8 == 0)
+        hex.append("\n");
+      hex.append(String.format("%08x ",raw[i]));
+    }
+    return hex.toString();
+  }
+  static void println(String format, Object... args) {
+    System.out.println(String.format(format,args)); 
+  }
+  static void print(String format, Object... args) {
+    System.out.print(String.format(format,args)); 
+  }
+}
Index: lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java	(revision 1351317)
+++ lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java	(working copy)
@@ -76,7 +76,7 @@
 // we won't even be running the actual code, only the impostor
 // @SuppressCodecs("Lucene4x")
 // Sep codec cannot yet handle the offsets in our 4.x index!
-@SuppressCodecs({"MockFixedIntBlock", "MockVariableIntBlock", "MockSep", "MockRandom"})
+@SuppressCodecs({"MockFixedIntBlock", "MockVariableIntBlock", "MockSep", "MockRandom","PFor"})
 public class TestBackwardsCompatibility extends LuceneTestCase {
 
   // Uncomment these cases & run them on an older Lucene
Index: lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java	(revision 1351317)
+++ lucene/core/src/test/org/apache/lucene/index/TestPostingsOffsets.java	(working copy)
@@ -49,7 +49,7 @@
 // TODO: we really need to test indexingoffsets, but then getting only docs / docs + freqs.
 // not all codecs store prx separate...
 // TODO: fix sep codec to index offsets so we can greatly reduce this list!
-@SuppressCodecs({"MockFixedIntBlock", "MockVariableIntBlock", "MockSep", "MockRandom"})
+@SuppressCodecs({"MockFixedIntBlock", "MockVariableIntBlock", "MockSep", "MockRandom","PFor"})
 public class TestPostingsOffsets extends LuceneTestCase {
   IndexWriterConfig iwc;
   
@@ -438,14 +438,6 @@
     }
   }
   
-  public void testStackedTokens() throws Exception {
-    checkTokens(new Token[] { 
-        makeToken("foo", 1, 0, 3),
-        makeToken("foo", 0, 0, 3),
-        makeToken("foo", 0, 0, 3)
-     });
-  }
-  
   public void testLegalbutVeryLargeOffsets() throws Exception {
     Directory dir = newDirectory();
     IndexWriter iw = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
Index: lucene/core/src/java/org/apache/lucene/codecs/pfor/PForUtil.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/pfor/PForUtil.java	(revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/pfor/PForUtil.java	(working copy)
@@ -0,0 +1,376 @@
+package org.apache.lucene.codecs.pfor;
+/**
+ * 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.
+ */
+
+import java.nio.IntBuffer;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+// Encode all small values and exception pointers in normal area, 
+// Encode large values in exception area.
+// Size per exception is variable, possibly: 1byte, 2bytes, or 4bytes
+// TODO: force exception is unnecessary when no following exception is
+// assumed, therefore we should caculate numExceptions ahead?
+// for example, ints like: 0,0xffffffff,0,1,0,1,0,1,0,1,0,1,0,1
+// will force all '1's as exceptions
+public final class PForUtil {
+  public static final int HEADER_INT_SIZE=1;
+  // TODO: memory access should be slower than ad-hoc bit shift
+  // remove this table if bottleneck lies here
+  private static final int[] MASK = {   0x00000000,
+    0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f,
+    0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
+    0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff,
+    0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
+    0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff,
+    0x7fffffff, 0xffffffff};
+  protected static final int[] PER_EXCEPTION_SIZE = {1,2,4};
+
+  public static int compress(final int[] data, int size, IntBuffer intBuffer) {
+    int numBits=getNumBits(data,size);
+  
+    int[] excValues = new int[size];
+    int excNum = 0, excLastPos = -1, excFirstPos = -1;
+    int excLastNonForcePos = -1; 
+    int excNumBase = 0;       // num of exception until the last non-force exception
+    int excBytes = 1;         // bytes per exception
+    int excByteOffset = 0;    // bytes of preceeding codes like header and normal area
+    long maxChain = (1<<8) - 2;  // header bits limits this to 254
+    boolean conValue, conForce, conEnd;
+    int i=0;
+
+    // estimate exceptions
+    for (i=0; i<size; ++i) {
+      conValue = ((data[i] & MASK[numBits]) != data[i]); // value exception
+      conForce = (i >= maxChain + excLastPos);           // force exception
+      if (conValue || conForce) {
+        excValues[excNum++] = data[i];
+        if (excLastPos == -1) {
+          maxChain = 1L<<numBits; 
+          excFirstPos = i;
+        }
+        if (conValue) {
+          excLastNonForcePos = i;
+          excNumBase = excNum;
+        }
+        excLastPos = i;
+      }
+    }
+
+    // encode normal area, record exception positions
+    i=0;
+    excNum = 0;
+    if (excFirstPos < 0) { // no exception 
+      for (; i<size; ++i) {
+        encodeNormalValue(intBuffer,i,data[i], numBits);
+      }
+      excLastPos = -1;
+    } else {
+      for (; i<excFirstPos; ++i) {
+        encodeNormalValue(intBuffer,i,data[i], numBits);
+      }
+      maxChain = 1L<<numBits;
+      excLastPos = -1;
+      for (; i<size; ++i) {
+        conValue = ((data[i] & MASK[numBits]) != data[i]); // value exception
+        conForce = (i >= maxChain + excLastPos);           // force exception
+        conEnd = (excNum == excNumBase);                   // following forced ignored
+        if ((!conValue && !conForce) || conEnd) {
+          encodeNormalValue(intBuffer,i,data[i], numBits);
+        } else {
+          if (excLastPos >= 0) {
+            encodeNormalValue(intBuffer, excLastPos, i-excLastPos-1, numBits); 
+          }
+          excNum++;
+          excLastPos = i;
+        }
+      }
+      if (excLastPos >= 0) { 
+        encodeNormalValue(intBuffer, excLastPos, (i-excLastPos-1)&MASK[numBits], numBits); // mask out suppressed force exception
+      }
+    }
+  
+    // encode exception area
+    i=0;
+    for (; i<excNum; ++i) {
+      if (excBytes < 2 && (excValues[i] & ~MASK[8]) != 0) {
+        excBytes=2;
+      }
+      if (excBytes < 4 && (excValues[i] & ~MASK[16]) != 0) {
+        excBytes=4;
+      }
+    }
+    excByteOffset = HEADER_INT_SIZE*4 + (size*numBits + 7)/8;
+    encodeExcValues(intBuffer, excValues, excNum, excBytes, excByteOffset);
+
+    // encode header
+    encodeHeader(intBuffer, size, numBits, excNum, excFirstPos, excBytes);
+
+    return (excByteOffset + excBytes*excNum + 3)/4*4;
+  }
+  
+  public static int decompress(IntBuffer intBuffer, int[] data) {
+    intBuffer.rewind();
+    int header = intBuffer.get();
+
+    int numInts = (header & MASK[8]) + 1;
+    int excNum = ((header >> 8) & MASK[8]) + 1;
+    int excFirstPos = ((header >> 16) & MASK[8]) - 1;
+    int excBytes = PER_EXCEPTION_SIZE[(header >> 29) & MASK[2]];
+    int numBits = ((header >> 24) & MASK[5]) + 1;
+
+    // TODO: PForDecompressImpl is hardewired to size==128 only
+    switch(numBits) {
+      case 1: PForDecompressImpl.decode1(intBuffer, data); break;
+      case 2: PForDecompressImpl.decode2(intBuffer, data); break;
+      case 3: PForDecompressImpl.decode3(intBuffer, data); break;
+      case 4: PForDecompressImpl.decode4(intBuffer, data); break;
+      case 5: PForDecompressImpl.decode5(intBuffer, data); break;
+      case 6: PForDecompressImpl.decode6(intBuffer, data); break;
+      case 7: PForDecompressImpl.decode7(intBuffer, data); break;
+      case 8: PForDecompressImpl.decode8(intBuffer, data); break;
+      case 9: PForDecompressImpl.decode9(intBuffer, data); break;
+      case 10: PForDecompressImpl.decode10(intBuffer, data); break;
+      case 11: PForDecompressImpl.decode11(intBuffer, data); break;
+      case 12: PForDecompressImpl.decode12(intBuffer, data); break;
+      case 13: PForDecompressImpl.decode13(intBuffer, data); break;
+      case 14: PForDecompressImpl.decode14(intBuffer, data); break;
+      case 15: PForDecompressImpl.decode15(intBuffer, data); break;
+      case 16: PForDecompressImpl.decode16(intBuffer, data); break;
+      case 17: PForDecompressImpl.decode17(intBuffer, data); break;
+      case 18: PForDecompressImpl.decode18(intBuffer, data); break;
+      case 19: PForDecompressImpl.decode19(intBuffer, data); break;
+      case 20: PForDecompressImpl.decode20(intBuffer, data); break;
+      case 21: PForDecompressImpl.decode21(intBuffer, data); break;
+      case 22: PForDecompressImpl.decode22(intBuffer, data); break;
+      case 23: PForDecompressImpl.decode23(intBuffer, data); break;
+      case 24: PForDecompressImpl.decode24(intBuffer, data); break;
+      case 25: PForDecompressImpl.decode25(intBuffer, data); break;
+      case 26: PForDecompressImpl.decode26(intBuffer, data); break;
+      case 27: PForDecompressImpl.decode27(intBuffer, data); break;
+      case 28: PForDecompressImpl.decode28(intBuffer, data); break;
+      case 29: PForDecompressImpl.decode29(intBuffer, data); break;
+      case 30: PForDecompressImpl.decode30(intBuffer, data); break;
+      case 31: PForDecompressImpl.decode31(intBuffer, data); break;
+      case 32: PForDecompressImpl.decode32(intBuffer, data); break;
+      default:
+        throw new IllegalStateException("Unknown numFrameBits " + numBits);
+    }
+    patchException(intBuffer,data,excNum,excFirstPos,excBytes);
+    return numInts;
+  }
+
+  static void encodeHeader(IntBuffer intBuffer, int numInts, int numBits, int excNum, int excFirstPos, int excBytes) {
+    int header = getHeader(numInts,numBits,excNum,excFirstPos,excBytes);
+    intBuffer.put(0, header);
+  }
+
+  static void encodeExcValues(IntBuffer intBuffer, int[] values, int num, int perbytes, int byteOffset) {
+    if (num == 0)
+      return;
+    if (perbytes == 1) {
+      int curBytePos = byteOffset;
+      for (int i=0; i<num; ++i) {
+        int curIntPos = curBytePos / 4;
+        setBufferIntBits(intBuffer, curIntPos, (curBytePos & 3)*8, 8, values[i]);
+        curBytePos++;
+      }
+    } else if (perbytes == 2) {
+      int shortOffset = (byteOffset+1)/2;
+      int curIntPos = shortOffset/2;
+      int i=0;
+      if ((shortOffset & 1) == 1) {  // cut head to ensure remaining fit ints
+        setBufferIntBits(intBuffer, curIntPos++, 16, 16, values[i++]); 
+      }
+      for (; i<num-1; i+=2) {
+        intBuffer.put(curIntPos++, (values[i+1]<<16) | values[i]);
+      }
+      if (i<num) {
+        intBuffer.put(curIntPos, values[i]); // cut tail, also clear high 16 bits
+      }
+    } else if (perbytes == 4) {
+      int curIntPos = (byteOffset+3) / 4;
+      for (int i=0; i<num; ++i) {
+        intBuffer.put(curIntPos++, values[i]);
+      }
+    }
+  }
+
+  static void encodeNormalValue(IntBuffer intBuffer, int pos, int value, int numBits) {
+    final int globalBitPos = numBits*pos;         // position in bit stream
+    final int localBitPos = globalBitPos & 31;    // position inside an int
+    int intPos = HEADER_INT_SIZE + globalBitPos/32;   // which integer to locate 
+    setBufferIntBits(intBuffer, intPos, localBitPos, numBits, value);
+    if ((localBitPos + numBits) > 32) { // value does not fit in this int, fill tail
+      setBufferIntBits(intBuffer, intPos+1, 0, 
+                       (localBitPos+numBits-32), 
+                       (value >>> (32-localBitPos)));
+    }
+  }
+
+  // TODO: since numInts===128, we don't need to rewind intBuffer.
+  // however, tail of normal area may share a same int with head of exception area
+  // which means patchException may lose heading exceptions.
+  public static void patchException(IntBuffer intBuffer, int[] data, int excNum, int excFirstPos, int excBytes) {
+    if (excFirstPos == -1) {
+      return;
+    }
+    int curPos=excFirstPos;
+    int i,j;
+
+    if (excBytes == 1) {
+      for (i=0; i+3<excNum; i+=4) {
+        final int curInt = intBuffer.get();
+        curPos = patch(data, curPos, (curInt) & MASK[8]);
+        curPos = patch(data, curPos, (curInt >>> 8)  & MASK[8]);
+        curPos = patch(data, curPos, (curInt >>> 16) & MASK[8]);
+        curPos = patch(data, curPos, (curInt >>> 24) & MASK[8]);
+      }
+      if (i<excNum) { 
+        final int curInt = intBuffer.get();
+        for (j=0; j<32 && i<excNum; j+=8,i++) {
+          curPos = patch(data, curPos, (curInt >>> j) & MASK[8]);
+        }
+      }
+    } else if (excBytes == 2) {
+      for (i=0; i+1<excNum; i+=2) {
+        final int curInt = intBuffer.get();
+        curPos = patch(data, curPos, (curInt) & MASK[16]);
+        curPos = patch(data, curPos, (curInt >>> 16) & MASK[16]);
+      }
+      if (i<excNum) {
+        final int curInt = intBuffer.get();
+        curPos = patch(data, curPos, (curInt) & MASK[16]);
+      }
+    } else if (excBytes == 4) {
+      for (i=0; i<excNum; i++) {
+        curPos = patch(data, curPos, intBuffer.get());
+      }
+    }
+  }
+
+  static int patch(int[]data, int pos, int value) {
+    int nextPos = data[pos] + pos + 1;
+    data[pos] = value;
+    assert nextPos > pos;
+    return nextPos;
+  }
+
+  static void setBufferIntBits(IntBuffer intBuffer, int intPos, int firstBitPos, int numBits, int value) {
+    assert (value & ~MASK[numBits]) == 0;
+    // safely discards those msb parts when firstBitPos+numBits>32
+    intBuffer.put(intPos,
+          (intBuffer.get(intPos) & ~(MASK[numBits] << firstBitPos)) 
+          | (value << firstBitPos));
+  }
+
+  // TODO: shall we use 32 NumBits directly if it exceeds 28 bits?
+  static int getNumBits(final int[] data, int size) {
+    int optBits=1;
+    int optSize=estimateCompressedSize(data,size,1);
+    for (int i=2; i<=32; ++i) {
+      int curSize=estimateCompressedSize(data,size,i);
+      if (curSize<optSize) {
+        optSize=curSize;
+        optBits=i;
+      }
+    }
+    return optBits;
+  }
+
+  // loosely estimate int size of each compressed block, based on parameter b
+  // ignore force exceptions
+  static int estimateCompressedSize(final int[] data, int size, int numBits) {
+    int totalBytes=(numBits*size+7)/8;   // always round to byte
+    int excNum=0;
+    int curExcBytes=1;
+    for (int i=0; i<size; ++i) {
+      if ((data[i] & ~MASK[numBits]) != 0) {   // exception
+        excNum++;
+        if (curExcBytes<2 && (data[i] & ~MASK[8]) != 0) { // exceed 1 byte exception
+          curExcBytes=2;
+        }
+        if (curExcBytes<4 && (data[i] & ~MASK[16]) != 0) { // exceed 2 byte exception
+          curExcBytes=4;
+        }
+      }
+    }
+    if (curExcBytes==2) {
+      totalBytes=((totalBytes+1)/2)*2;  // round up to 2x bytes before filling exceptions
+    }
+    else if (curExcBytes==4) {
+      totalBytes=((totalBytes+3)/4)*4;  // round up to 4x bytes
+    }
+    totalBytes+=excNum*curExcBytes;
+
+    return totalBytes/4*4+HEADER_INT_SIZE;  // round up to ints
+  }
+  /** The 4 byte header (32 bits) contains (from lsb to msb):
+   *
+   * - 8 bits for uncompressed int num - 1 (use up to 7 bits i.e 128 actually)
+   *
+   * - 8 bits for exception num - 1 (when no exceptions, this is undefined)
+   *
+   * - 8 bits for the index of the first exception + 1 (when no exception, this is 0)
+   *
+   * - 5 bits for num of frame bits - 1
+   * - 2 bits for the exception code: 00: byte, 01: short, 10: int
+   * - 1 bit unused
+   *
+   */
+  static int getHeader(int numInts, int numBits, int excNum, int excFirstPos, int excBytes) {
+    return  (numInts-1)
+          | (((excNum-1) & MASK[8]) << 8)
+          | ((excFirstPos+1) << 16)
+          | ((numBits-1) << 24)
+          | ((excBytes/2) << 29);
+  }
+
+  static void println(String format, Object... args) {
+    System.out.println(String.format(format,args)); 
+  }
+  static void print(String format, Object... args) {
+    System.out.print(String.format(format,args)); 
+  }
+  static void eprintln(String format, Object... args) {
+    System.err.println(String.format(format,args)); 
+  }
+  public static String getHex( byte [] raw, int sz ) {
+    final String HEXES = "0123456789ABCDEF";
+    if ( raw == null ) return null;
+    final StringBuilder hex = new StringBuilder( 2 * raw.length );
+    for ( int i=0; i<sz; i++ ) {
+      if (i>0 && (i)%16 == 0)
+        hex.append("\n");
+      byte b=raw[i];
+      hex.append(HEXES.charAt((b & 0xF0) >> 4))
+         .append(HEXES.charAt((b & 0x0F)))
+         .append(" ");
+    }
+    return hex.toString();
+  }
+  public static String getHex( int [] raw, int sz ) {
+    if ( raw == null ) return null;
+    final StringBuilder hex = new StringBuilder( 4 * raw.length );
+    for ( int i=0; i<sz; i++ ) {
+      if (i>0 && i%8 == 0)
+        hex.append("\n");
+      hex.append(String.format("%08x ",raw[i]));
+    }
+    return hex.toString();
+  }
+}
Index: lucene/core/src/java/org/apache/lucene/codecs/pfor/gendecompress.py
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/pfor/gendecompress.py	(revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/pfor/gendecompress.py	(working copy)
@@ -0,0 +1,125 @@
+#!/usr/bin/env python2
+"""
+  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.
+"""
+
+"""
+Generate source code for java classes for FOR decompression.
+"""
+
+USE_SCRATCH = False
+#USE_SCRATCH = True 
+
+def bitsExpr(i, numFrameBits):
+  framePos = i * numFrameBits
+  intValNum = (framePos / 32)
+  bitPos = framePos % 32
+  if USE_SCRATCH:
+    bitsInInt = "inputInts[" + str(intValNum) + "]"
+  else:
+    bitsInInt = "intValue" + str(intValNum)
+  needBrackets = 0
+  if bitPos > 0:
+    bitsInInt +=  " >>> " + str(bitPos)
+    needBrackets = 1
+  if bitPos + numFrameBits > 32:
+    if needBrackets:
+      bitsInInt = "(" + bitsInInt + ")"
+    if USE_SCRATCH:
+      bitsInInt += " | (inputInts[" + str(intValNum+1) + "] << "+ str(32 - bitPos) + ")"
+    else:
+      bitsInInt += " | (intValue" + str(intValNum+1) + " << "+ str(32 - bitPos) + ")"
+    needBrackets = 1
+  if bitPos + numFrameBits != 32:
+    if needBrackets:
+      bitsInInt = "(" + bitsInInt + ")"
+    bitsInInt += " & mask"
+  return bitsInInt
+
+
+def genDecompress():
+  className = "PForDecompressImpl"
+  fileName = className + ".java"
+  imports = "import java.nio.IntBuffer;\n"
+  f = open(fileName, 'w')
+  w = f.write
+  try:
+    w("package org.apache.lucene.codecs.pfor;\n")
+    w("""/**
+ * 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.
+ */
+ """)
+
+    w("/* This code is generated, do not modify. See gendecompress.py */\n\n")
+
+    w("import java.nio.IntBuffer;\n\n")
+
+    w("final class PForDecompressImpl {\n")
+
+    w('\n  // nocommit: assess perf of this to see if specializing is really needed\n')
+
+    # previous version only handle int less(or equal) than 31 bits
+    # try to support 32 bits here
+    for numFrameBits in xrange(1, 33):
+
+      w('\n  // NOTE: hardwired to blockSize == 128\n')
+      if USE_SCRATCH:
+        w('  public static void decode%d(final IntBuffer compressedBuffer, final int[] output, final int[] scratch) {\n' % numFrameBits)
+      else:
+        w('  public static void decode%d(final IntBuffer compressedBuffer, final int[] output) {\n' % numFrameBits)
+
+      w('    final int numFrameBits = %d;\n' % numFrameBits)
+      w('    final int mask = (int) ((1L<<numFrameBits) - 1);\n')
+      w('    int outputOffset = 0;\n')
+      
+      w('    for(int step=0;step<4;step++) {\n')
+
+      if USE_SCRATCH:
+        w('      compressedBuffer.get(scratch, 0, %d);\n' % numFrameBits)
+      else:
+        for i in range(numFrameBits): # declare int vars and init from buffer
+          w("      int intValue" + str(i) + " = compressedBuffer.get();\n")
+
+      for i in range(32): # set output from int vars
+        w("      output[" + str(i) + " + outputOffset] = " + bitsExpr(i, numFrameBits) + ";\n")
+      w('      outputOffset += 32;\n')
+      w('    }\n')
+      w('  }\n')
+    w('}\n')
+      
+  finally:
+    f.close()
+
+def genSwitch():
+  for numFrameBits in xrange(1, 33):
+    print '      case %d: PForDecompressImpl.decode%d(compressedBuffer, encoded); break;' % (numFrameBits, numFrameBits)
+
+if __name__ == "__main__":
+  genDecompress()
+  #genSwitch()

Property changes on: lucene/core/src/java/org/apache/lucene/codecs/pfor/gendecompress.py
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: lucene/core/src/java/org/apache/lucene/codecs/pfor/PForPostingsFormat.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/pfor/PForPostingsFormat.java	(revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/pfor/PForPostingsFormat.java	(working copy)
@@ -0,0 +1,117 @@
+package org.apache.lucene.codecs.pfor;
+/**
+ * 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.
+ */
+
+import java.util.Set;
+import java.io.IOException;
+
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.store.IOContext;
+import org.apache.lucene.index.SegmentInfo;
+import org.apache.lucene.index.SegmentWriteState;
+import org.apache.lucene.index.SegmentReadState;
+import org.apache.lucene.codecs.FieldsConsumer;
+import org.apache.lucene.codecs.FieldsProducer;
+import org.apache.lucene.codecs.BlockTreeTermsWriter;
+import org.apache.lucene.codecs.BlockTreeTermsReader;
+import org.apache.lucene.codecs.TermsIndexReaderBase;
+import org.apache.lucene.codecs.TermsIndexWriterBase;
+import org.apache.lucene.codecs.FixedGapTermsIndexReader;
+import org.apache.lucene.codecs.FixedGapTermsIndexWriter;
+import org.apache.lucene.codecs.PostingsFormat;
+import org.apache.lucene.codecs.PostingsWriterBase;
+import org.apache.lucene.codecs.PostingsReaderBase;
+import org.apache.lucene.codecs.sep.SepPostingsReader;
+import org.apache.lucene.codecs.sep.SepPostingsWriter;
+/**
+ * This class actually only pass the PForFactory
+ * to a PostingsWriter/ReaderBase, and get customized
+ * format plugged.
+ */
+public class PForPostingsFormat extends PostingsFormat {
+  private final int blockSize;
+  private final int minBlockSize;
+  private final int maxBlockSize;
+  protected final static int DEFAULT_BLOCK_SIZE = 128;
+  protected final static int DEFAULT_TERM_CACHED_SIZE = 1024;
+
+  public PForPostingsFormat() {
+    super("PFor");
+    this.blockSize = DEFAULT_BLOCK_SIZE;
+    this.minBlockSize = BlockTreeTermsWriter.DEFAULT_MIN_BLOCK_SIZE;
+    this.maxBlockSize = BlockTreeTermsWriter.DEFAULT_MAX_BLOCK_SIZE;
+  }
+  public PForPostingsFormat(int minBlockSize, int maxBlockSize) {
+    super("PFor");
+    this.blockSize = DEFAULT_BLOCK_SIZE;
+    this.minBlockSize = minBlockSize;
+    assert minBlockSize > 1;
+    this.maxBlockSize = maxBlockSize;
+    assert minBlockSize <= maxBlockSize;
+  }
+
+  @Override
+  public String toString() {
+    return getName() + "(blocksize=" + blockSize + ")";
+  }
+
+  @Override
+  public FieldsConsumer fieldsConsumer(SegmentWriteState state) throws IOException {
+    // TODO: implement a new PostingsWriterBase to improve skip-settings
+    PostingsWriterBase postingsWriter = new SepPostingsWriter(state, new PForFactory()); 
+    boolean success = false;
+    try {
+      FieldsConsumer ret = new BlockTreeTermsWriter(state, 
+                                                    postingsWriter,
+                                                    minBlockSize, 
+                                                    maxBlockSize);
+      success = true;
+      return ret;
+    } finally {
+      if (!success) {
+        postingsWriter.close();
+      }
+    }
+  }
+
+  @Override
+  public FieldsProducer fieldsProducer(SegmentReadState state) throws IOException {
+    PostingsReaderBase postingsReader = new SepPostingsReader(state.dir,
+                                                              state.fieldInfos,
+                                                              state.segmentInfo,
+                                                              state.context,
+                                                              new PForFactory(),
+                                                              state.segmentSuffix);
+
+    boolean success = false;
+    try {
+      FieldsProducer ret = new BlockTreeTermsReader(state.dir,
+                                                    state.fieldInfos,
+                                                    state.segmentInfo.name,
+                                                    postingsReader,
+                                                    state.context,
+                                                    state.segmentSuffix,
+                                                    state.termsIndexDivisor);
+      success = true;
+      return ret;
+    } finally {
+      if (!success) {
+        postingsReader.close();
+      }
+    }
+  }
+}
Index: lucene/core/src/java/org/apache/lucene/codecs/pfor/PForDecompressImpl.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/pfor/PForDecompressImpl.java	(revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/pfor/PForDecompressImpl.java	(working copy)
@@ -0,0 +1,1897 @@
+package org.apache.lucene.codecs.pfor;
+/**
+ * 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.
+ */
+ /* This code is generated, do not modify. See gendecompress.py */
+
+import java.nio.IntBuffer;
+
+final class PForDecompressImpl {
+
+  // nocommit: assess perf of this to see if specializing is really needed
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode1(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 1;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 1) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 2) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 3) & mask;
+      output[4 + outputOffset] = (intValue0 >>> 4) & mask;
+      output[5 + outputOffset] = (intValue0 >>> 5) & mask;
+      output[6 + outputOffset] = (intValue0 >>> 6) & mask;
+      output[7 + outputOffset] = (intValue0 >>> 7) & mask;
+      output[8 + outputOffset] = (intValue0 >>> 8) & mask;
+      output[9 + outputOffset] = (intValue0 >>> 9) & mask;
+      output[10 + outputOffset] = (intValue0 >>> 10) & mask;
+      output[11 + outputOffset] = (intValue0 >>> 11) & mask;
+      output[12 + outputOffset] = (intValue0 >>> 12) & mask;
+      output[13 + outputOffset] = (intValue0 >>> 13) & mask;
+      output[14 + outputOffset] = (intValue0 >>> 14) & mask;
+      output[15 + outputOffset] = (intValue0 >>> 15) & mask;
+      output[16 + outputOffset] = (intValue0 >>> 16) & mask;
+      output[17 + outputOffset] = (intValue0 >>> 17) & mask;
+      output[18 + outputOffset] = (intValue0 >>> 18) & mask;
+      output[19 + outputOffset] = (intValue0 >>> 19) & mask;
+      output[20 + outputOffset] = (intValue0 >>> 20) & mask;
+      output[21 + outputOffset] = (intValue0 >>> 21) & mask;
+      output[22 + outputOffset] = (intValue0 >>> 22) & mask;
+      output[23 + outputOffset] = (intValue0 >>> 23) & mask;
+      output[24 + outputOffset] = (intValue0 >>> 24) & mask;
+      output[25 + outputOffset] = (intValue0 >>> 25) & mask;
+      output[26 + outputOffset] = (intValue0 >>> 26) & mask;
+      output[27 + outputOffset] = (intValue0 >>> 27) & mask;
+      output[28 + outputOffset] = (intValue0 >>> 28) & mask;
+      output[29 + outputOffset] = (intValue0 >>> 29) & mask;
+      output[30 + outputOffset] = (intValue0 >>> 30) & mask;
+      output[31 + outputOffset] = intValue0 >>> 31;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode2(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 2;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 2) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 4) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 6) & mask;
+      output[4 + outputOffset] = (intValue0 >>> 8) & mask;
+      output[5 + outputOffset] = (intValue0 >>> 10) & mask;
+      output[6 + outputOffset] = (intValue0 >>> 12) & mask;
+      output[7 + outputOffset] = (intValue0 >>> 14) & mask;
+      output[8 + outputOffset] = (intValue0 >>> 16) & mask;
+      output[9 + outputOffset] = (intValue0 >>> 18) & mask;
+      output[10 + outputOffset] = (intValue0 >>> 20) & mask;
+      output[11 + outputOffset] = (intValue0 >>> 22) & mask;
+      output[12 + outputOffset] = (intValue0 >>> 24) & mask;
+      output[13 + outputOffset] = (intValue0 >>> 26) & mask;
+      output[14 + outputOffset] = (intValue0 >>> 28) & mask;
+      output[15 + outputOffset] = intValue0 >>> 30;
+      output[16 + outputOffset] = intValue1 & mask;
+      output[17 + outputOffset] = (intValue1 >>> 2) & mask;
+      output[18 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[19 + outputOffset] = (intValue1 >>> 6) & mask;
+      output[20 + outputOffset] = (intValue1 >>> 8) & mask;
+      output[21 + outputOffset] = (intValue1 >>> 10) & mask;
+      output[22 + outputOffset] = (intValue1 >>> 12) & mask;
+      output[23 + outputOffset] = (intValue1 >>> 14) & mask;
+      output[24 + outputOffset] = (intValue1 >>> 16) & mask;
+      output[25 + outputOffset] = (intValue1 >>> 18) & mask;
+      output[26 + outputOffset] = (intValue1 >>> 20) & mask;
+      output[27 + outputOffset] = (intValue1 >>> 22) & mask;
+      output[28 + outputOffset] = (intValue1 >>> 24) & mask;
+      output[29 + outputOffset] = (intValue1 >>> 26) & mask;
+      output[30 + outputOffset] = (intValue1 >>> 28) & mask;
+      output[31 + outputOffset] = intValue1 >>> 30;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode3(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 3;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 3) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 6) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 9) & mask;
+      output[4 + outputOffset] = (intValue0 >>> 12) & mask;
+      output[5 + outputOffset] = (intValue0 >>> 15) & mask;
+      output[6 + outputOffset] = (intValue0 >>> 18) & mask;
+      output[7 + outputOffset] = (intValue0 >>> 21) & mask;
+      output[8 + outputOffset] = (intValue0 >>> 24) & mask;
+      output[9 + outputOffset] = (intValue0 >>> 27) & mask;
+      output[10 + outputOffset] = ((intValue0 >>> 30) | (intValue1 << 2)) & mask;
+      output[11 + outputOffset] = (intValue1 >>> 1) & mask;
+      output[12 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[13 + outputOffset] = (intValue1 >>> 7) & mask;
+      output[14 + outputOffset] = (intValue1 >>> 10) & mask;
+      output[15 + outputOffset] = (intValue1 >>> 13) & mask;
+      output[16 + outputOffset] = (intValue1 >>> 16) & mask;
+      output[17 + outputOffset] = (intValue1 >>> 19) & mask;
+      output[18 + outputOffset] = (intValue1 >>> 22) & mask;
+      output[19 + outputOffset] = (intValue1 >>> 25) & mask;
+      output[20 + outputOffset] = (intValue1 >>> 28) & mask;
+      output[21 + outputOffset] = ((intValue1 >>> 31) | (intValue2 << 1)) & mask;
+      output[22 + outputOffset] = (intValue2 >>> 2) & mask;
+      output[23 + outputOffset] = (intValue2 >>> 5) & mask;
+      output[24 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[25 + outputOffset] = (intValue2 >>> 11) & mask;
+      output[26 + outputOffset] = (intValue2 >>> 14) & mask;
+      output[27 + outputOffset] = (intValue2 >>> 17) & mask;
+      output[28 + outputOffset] = (intValue2 >>> 20) & mask;
+      output[29 + outputOffset] = (intValue2 >>> 23) & mask;
+      output[30 + outputOffset] = (intValue2 >>> 26) & mask;
+      output[31 + outputOffset] = intValue2 >>> 29;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode4(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 4;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 4) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 8) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 12) & mask;
+      output[4 + outputOffset] = (intValue0 >>> 16) & mask;
+      output[5 + outputOffset] = (intValue0 >>> 20) & mask;
+      output[6 + outputOffset] = (intValue0 >>> 24) & mask;
+      output[7 + outputOffset] = intValue0 >>> 28;
+      output[8 + outputOffset] = intValue1 & mask;
+      output[9 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[10 + outputOffset] = (intValue1 >>> 8) & mask;
+      output[11 + outputOffset] = (intValue1 >>> 12) & mask;
+      output[12 + outputOffset] = (intValue1 >>> 16) & mask;
+      output[13 + outputOffset] = (intValue1 >>> 20) & mask;
+      output[14 + outputOffset] = (intValue1 >>> 24) & mask;
+      output[15 + outputOffset] = intValue1 >>> 28;
+      output[16 + outputOffset] = intValue2 & mask;
+      output[17 + outputOffset] = (intValue2 >>> 4) & mask;
+      output[18 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[19 + outputOffset] = (intValue2 >>> 12) & mask;
+      output[20 + outputOffset] = (intValue2 >>> 16) & mask;
+      output[21 + outputOffset] = (intValue2 >>> 20) & mask;
+      output[22 + outputOffset] = (intValue2 >>> 24) & mask;
+      output[23 + outputOffset] = intValue2 >>> 28;
+      output[24 + outputOffset] = intValue3 & mask;
+      output[25 + outputOffset] = (intValue3 >>> 4) & mask;
+      output[26 + outputOffset] = (intValue3 >>> 8) & mask;
+      output[27 + outputOffset] = (intValue3 >>> 12) & mask;
+      output[28 + outputOffset] = (intValue3 >>> 16) & mask;
+      output[29 + outputOffset] = (intValue3 >>> 20) & mask;
+      output[30 + outputOffset] = (intValue3 >>> 24) & mask;
+      output[31 + outputOffset] = intValue3 >>> 28;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode5(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 5;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 5) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 10) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 15) & mask;
+      output[4 + outputOffset] = (intValue0 >>> 20) & mask;
+      output[5 + outputOffset] = (intValue0 >>> 25) & mask;
+      output[6 + outputOffset] = ((intValue0 >>> 30) | (intValue1 << 2)) & mask;
+      output[7 + outputOffset] = (intValue1 >>> 3) & mask;
+      output[8 + outputOffset] = (intValue1 >>> 8) & mask;
+      output[9 + outputOffset] = (intValue1 >>> 13) & mask;
+      output[10 + outputOffset] = (intValue1 >>> 18) & mask;
+      output[11 + outputOffset] = (intValue1 >>> 23) & mask;
+      output[12 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[13 + outputOffset] = (intValue2 >>> 1) & mask;
+      output[14 + outputOffset] = (intValue2 >>> 6) & mask;
+      output[15 + outputOffset] = (intValue2 >>> 11) & mask;
+      output[16 + outputOffset] = (intValue2 >>> 16) & mask;
+      output[17 + outputOffset] = (intValue2 >>> 21) & mask;
+      output[18 + outputOffset] = (intValue2 >>> 26) & mask;
+      output[19 + outputOffset] = ((intValue2 >>> 31) | (intValue3 << 1)) & mask;
+      output[20 + outputOffset] = (intValue3 >>> 4) & mask;
+      output[21 + outputOffset] = (intValue3 >>> 9) & mask;
+      output[22 + outputOffset] = (intValue3 >>> 14) & mask;
+      output[23 + outputOffset] = (intValue3 >>> 19) & mask;
+      output[24 + outputOffset] = (intValue3 >>> 24) & mask;
+      output[25 + outputOffset] = ((intValue3 >>> 29) | (intValue4 << 3)) & mask;
+      output[26 + outputOffset] = (intValue4 >>> 2) & mask;
+      output[27 + outputOffset] = (intValue4 >>> 7) & mask;
+      output[28 + outputOffset] = (intValue4 >>> 12) & mask;
+      output[29 + outputOffset] = (intValue4 >>> 17) & mask;
+      output[30 + outputOffset] = (intValue4 >>> 22) & mask;
+      output[31 + outputOffset] = intValue4 >>> 27;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode6(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 6;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 6) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 12) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 18) & mask;
+      output[4 + outputOffset] = (intValue0 >>> 24) & mask;
+      output[5 + outputOffset] = ((intValue0 >>> 30) | (intValue1 << 2)) & mask;
+      output[6 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[7 + outputOffset] = (intValue1 >>> 10) & mask;
+      output[8 + outputOffset] = (intValue1 >>> 16) & mask;
+      output[9 + outputOffset] = (intValue1 >>> 22) & mask;
+      output[10 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[11 + outputOffset] = (intValue2 >>> 2) & mask;
+      output[12 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[13 + outputOffset] = (intValue2 >>> 14) & mask;
+      output[14 + outputOffset] = (intValue2 >>> 20) & mask;
+      output[15 + outputOffset] = intValue2 >>> 26;
+      output[16 + outputOffset] = intValue3 & mask;
+      output[17 + outputOffset] = (intValue3 >>> 6) & mask;
+      output[18 + outputOffset] = (intValue3 >>> 12) & mask;
+      output[19 + outputOffset] = (intValue3 >>> 18) & mask;
+      output[20 + outputOffset] = (intValue3 >>> 24) & mask;
+      output[21 + outputOffset] = ((intValue3 >>> 30) | (intValue4 << 2)) & mask;
+      output[22 + outputOffset] = (intValue4 >>> 4) & mask;
+      output[23 + outputOffset] = (intValue4 >>> 10) & mask;
+      output[24 + outputOffset] = (intValue4 >>> 16) & mask;
+      output[25 + outputOffset] = (intValue4 >>> 22) & mask;
+      output[26 + outputOffset] = ((intValue4 >>> 28) | (intValue5 << 4)) & mask;
+      output[27 + outputOffset] = (intValue5 >>> 2) & mask;
+      output[28 + outputOffset] = (intValue5 >>> 8) & mask;
+      output[29 + outputOffset] = (intValue5 >>> 14) & mask;
+      output[30 + outputOffset] = (intValue5 >>> 20) & mask;
+      output[31 + outputOffset] = intValue5 >>> 26;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode7(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 7;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 7) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 14) & mask;
+      output[3 + outputOffset] = (intValue0 >>> 21) & mask;
+      output[4 + outputOffset] = ((intValue0 >>> 28) | (intValue1 << 4)) & mask;
+      output[5 + outputOffset] = (intValue1 >>> 3) & mask;
+      output[6 + outputOffset] = (intValue1 >>> 10) & mask;
+      output[7 + outputOffset] = (intValue1 >>> 17) & mask;
+      output[8 + outputOffset] = (intValue1 >>> 24) & mask;
+      output[9 + outputOffset] = ((intValue1 >>> 31) | (intValue2 << 1)) & mask;
+      output[10 + outputOffset] = (intValue2 >>> 6) & mask;
+      output[11 + outputOffset] = (intValue2 >>> 13) & mask;
+      output[12 + outputOffset] = (intValue2 >>> 20) & mask;
+      output[13 + outputOffset] = ((intValue2 >>> 27) | (intValue3 << 5)) & mask;
+      output[14 + outputOffset] = (intValue3 >>> 2) & mask;
+      output[15 + outputOffset] = (intValue3 >>> 9) & mask;
+      output[16 + outputOffset] = (intValue3 >>> 16) & mask;
+      output[17 + outputOffset] = (intValue3 >>> 23) & mask;
+      output[18 + outputOffset] = ((intValue3 >>> 30) | (intValue4 << 2)) & mask;
+      output[19 + outputOffset] = (intValue4 >>> 5) & mask;
+      output[20 + outputOffset] = (intValue4 >>> 12) & mask;
+      output[21 + outputOffset] = (intValue4 >>> 19) & mask;
+      output[22 + outputOffset] = ((intValue4 >>> 26) | (intValue5 << 6)) & mask;
+      output[23 + outputOffset] = (intValue5 >>> 1) & mask;
+      output[24 + outputOffset] = (intValue5 >>> 8) & mask;
+      output[25 + outputOffset] = (intValue5 >>> 15) & mask;
+      output[26 + outputOffset] = (intValue5 >>> 22) & mask;
+      output[27 + outputOffset] = ((intValue5 >>> 29) | (intValue6 << 3)) & mask;
+      output[28 + outputOffset] = (intValue6 >>> 4) & mask;
+      output[29 + outputOffset] = (intValue6 >>> 11) & mask;
+      output[30 + outputOffset] = (intValue6 >>> 18) & mask;
+      output[31 + outputOffset] = intValue6 >>> 25;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode8(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 8;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 8) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 16) & mask;
+      output[3 + outputOffset] = intValue0 >>> 24;
+      output[4 + outputOffset] = intValue1 & mask;
+      output[5 + outputOffset] = (intValue1 >>> 8) & mask;
+      output[6 + outputOffset] = (intValue1 >>> 16) & mask;
+      output[7 + outputOffset] = intValue1 >>> 24;
+      output[8 + outputOffset] = intValue2 & mask;
+      output[9 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[10 + outputOffset] = (intValue2 >>> 16) & mask;
+      output[11 + outputOffset] = intValue2 >>> 24;
+      output[12 + outputOffset] = intValue3 & mask;
+      output[13 + outputOffset] = (intValue3 >>> 8) & mask;
+      output[14 + outputOffset] = (intValue3 >>> 16) & mask;
+      output[15 + outputOffset] = intValue3 >>> 24;
+      output[16 + outputOffset] = intValue4 & mask;
+      output[17 + outputOffset] = (intValue4 >>> 8) & mask;
+      output[18 + outputOffset] = (intValue4 >>> 16) & mask;
+      output[19 + outputOffset] = intValue4 >>> 24;
+      output[20 + outputOffset] = intValue5 & mask;
+      output[21 + outputOffset] = (intValue5 >>> 8) & mask;
+      output[22 + outputOffset] = (intValue5 >>> 16) & mask;
+      output[23 + outputOffset] = intValue5 >>> 24;
+      output[24 + outputOffset] = intValue6 & mask;
+      output[25 + outputOffset] = (intValue6 >>> 8) & mask;
+      output[26 + outputOffset] = (intValue6 >>> 16) & mask;
+      output[27 + outputOffset] = intValue6 >>> 24;
+      output[28 + outputOffset] = intValue7 & mask;
+      output[29 + outputOffset] = (intValue7 >>> 8) & mask;
+      output[30 + outputOffset] = (intValue7 >>> 16) & mask;
+      output[31 + outputOffset] = intValue7 >>> 24;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode9(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 9;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 9) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 18) & mask;
+      output[3 + outputOffset] = ((intValue0 >>> 27) | (intValue1 << 5)) & mask;
+      output[4 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[5 + outputOffset] = (intValue1 >>> 13) & mask;
+      output[6 + outputOffset] = (intValue1 >>> 22) & mask;
+      output[7 + outputOffset] = ((intValue1 >>> 31) | (intValue2 << 1)) & mask;
+      output[8 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[9 + outputOffset] = (intValue2 >>> 17) & mask;
+      output[10 + outputOffset] = ((intValue2 >>> 26) | (intValue3 << 6)) & mask;
+      output[11 + outputOffset] = (intValue3 >>> 3) & mask;
+      output[12 + outputOffset] = (intValue3 >>> 12) & mask;
+      output[13 + outputOffset] = (intValue3 >>> 21) & mask;
+      output[14 + outputOffset] = ((intValue3 >>> 30) | (intValue4 << 2)) & mask;
+      output[15 + outputOffset] = (intValue4 >>> 7) & mask;
+      output[16 + outputOffset] = (intValue4 >>> 16) & mask;
+      output[17 + outputOffset] = ((intValue4 >>> 25) | (intValue5 << 7)) & mask;
+      output[18 + outputOffset] = (intValue5 >>> 2) & mask;
+      output[19 + outputOffset] = (intValue5 >>> 11) & mask;
+      output[20 + outputOffset] = (intValue5 >>> 20) & mask;
+      output[21 + outputOffset] = ((intValue5 >>> 29) | (intValue6 << 3)) & mask;
+      output[22 + outputOffset] = (intValue6 >>> 6) & mask;
+      output[23 + outputOffset] = (intValue6 >>> 15) & mask;
+      output[24 + outputOffset] = ((intValue6 >>> 24) | (intValue7 << 8)) & mask;
+      output[25 + outputOffset] = (intValue7 >>> 1) & mask;
+      output[26 + outputOffset] = (intValue7 >>> 10) & mask;
+      output[27 + outputOffset] = (intValue7 >>> 19) & mask;
+      output[28 + outputOffset] = ((intValue7 >>> 28) | (intValue8 << 4)) & mask;
+      output[29 + outputOffset] = (intValue8 >>> 5) & mask;
+      output[30 + outputOffset] = (intValue8 >>> 14) & mask;
+      output[31 + outputOffset] = intValue8 >>> 23;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode10(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 10;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 10) & mask;
+      output[2 + outputOffset] = (intValue0 >>> 20) & mask;
+      output[3 + outputOffset] = ((intValue0 >>> 30) | (intValue1 << 2)) & mask;
+      output[4 + outputOffset] = (intValue1 >>> 8) & mask;
+      output[5 + outputOffset] = (intValue1 >>> 18) & mask;
+      output[6 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[7 + outputOffset] = (intValue2 >>> 6) & mask;
+      output[8 + outputOffset] = (intValue2 >>> 16) & mask;
+      output[9 + outputOffset] = ((intValue2 >>> 26) | (intValue3 << 6)) & mask;
+      output[10 + outputOffset] = (intValue3 >>> 4) & mask;
+      output[11 + outputOffset] = (intValue3 >>> 14) & mask;
+      output[12 + outputOffset] = ((intValue3 >>> 24) | (intValue4 << 8)) & mask;
+      output[13 + outputOffset] = (intValue4 >>> 2) & mask;
+      output[14 + outputOffset] = (intValue4 >>> 12) & mask;
+      output[15 + outputOffset] = intValue4 >>> 22;
+      output[16 + outputOffset] = intValue5 & mask;
+      output[17 + outputOffset] = (intValue5 >>> 10) & mask;
+      output[18 + outputOffset] = (intValue5 >>> 20) & mask;
+      output[19 + outputOffset] = ((intValue5 >>> 30) | (intValue6 << 2)) & mask;
+      output[20 + outputOffset] = (intValue6 >>> 8) & mask;
+      output[21 + outputOffset] = (intValue6 >>> 18) & mask;
+      output[22 + outputOffset] = ((intValue6 >>> 28) | (intValue7 << 4)) & mask;
+      output[23 + outputOffset] = (intValue7 >>> 6) & mask;
+      output[24 + outputOffset] = (intValue7 >>> 16) & mask;
+      output[25 + outputOffset] = ((intValue7 >>> 26) | (intValue8 << 6)) & mask;
+      output[26 + outputOffset] = (intValue8 >>> 4) & mask;
+      output[27 + outputOffset] = (intValue8 >>> 14) & mask;
+      output[28 + outputOffset] = ((intValue8 >>> 24) | (intValue9 << 8)) & mask;
+      output[29 + outputOffset] = (intValue9 >>> 2) & mask;
+      output[30 + outputOffset] = (intValue9 >>> 12) & mask;
+      output[31 + outputOffset] = intValue9 >>> 22;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode11(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 11;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 11) & mask;
+      output[2 + outputOffset] = ((intValue0 >>> 22) | (intValue1 << 10)) & mask;
+      output[3 + outputOffset] = (intValue1 >>> 1) & mask;
+      output[4 + outputOffset] = (intValue1 >>> 12) & mask;
+      output[5 + outputOffset] = ((intValue1 >>> 23) | (intValue2 << 9)) & mask;
+      output[6 + outputOffset] = (intValue2 >>> 2) & mask;
+      output[7 + outputOffset] = (intValue2 >>> 13) & mask;
+      output[8 + outputOffset] = ((intValue2 >>> 24) | (intValue3 << 8)) & mask;
+      output[9 + outputOffset] = (intValue3 >>> 3) & mask;
+      output[10 + outputOffset] = (intValue3 >>> 14) & mask;
+      output[11 + outputOffset] = ((intValue3 >>> 25) | (intValue4 << 7)) & mask;
+      output[12 + outputOffset] = (intValue4 >>> 4) & mask;
+      output[13 + outputOffset] = (intValue4 >>> 15) & mask;
+      output[14 + outputOffset] = ((intValue4 >>> 26) | (intValue5 << 6)) & mask;
+      output[15 + outputOffset] = (intValue5 >>> 5) & mask;
+      output[16 + outputOffset] = (intValue5 >>> 16) & mask;
+      output[17 + outputOffset] = ((intValue5 >>> 27) | (intValue6 << 5)) & mask;
+      output[18 + outputOffset] = (intValue6 >>> 6) & mask;
+      output[19 + outputOffset] = (intValue6 >>> 17) & mask;
+      output[20 + outputOffset] = ((intValue6 >>> 28) | (intValue7 << 4)) & mask;
+      output[21 + outputOffset] = (intValue7 >>> 7) & mask;
+      output[22 + outputOffset] = (intValue7 >>> 18) & mask;
+      output[23 + outputOffset] = ((intValue7 >>> 29) | (intValue8 << 3)) & mask;
+      output[24 + outputOffset] = (intValue8 >>> 8) & mask;
+      output[25 + outputOffset] = (intValue8 >>> 19) & mask;
+      output[26 + outputOffset] = ((intValue8 >>> 30) | (intValue9 << 2)) & mask;
+      output[27 + outputOffset] = (intValue9 >>> 9) & mask;
+      output[28 + outputOffset] = (intValue9 >>> 20) & mask;
+      output[29 + outputOffset] = ((intValue9 >>> 31) | (intValue10 << 1)) & mask;
+      output[30 + outputOffset] = (intValue10 >>> 10) & mask;
+      output[31 + outputOffset] = intValue10 >>> 21;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode12(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 12;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 12) & mask;
+      output[2 + outputOffset] = ((intValue0 >>> 24) | (intValue1 << 8)) & mask;
+      output[3 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[4 + outputOffset] = (intValue1 >>> 16) & mask;
+      output[5 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[6 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[7 + outputOffset] = intValue2 >>> 20;
+      output[8 + outputOffset] = intValue3 & mask;
+      output[9 + outputOffset] = (intValue3 >>> 12) & mask;
+      output[10 + outputOffset] = ((intValue3 >>> 24) | (intValue4 << 8)) & mask;
+      output[11 + outputOffset] = (intValue4 >>> 4) & mask;
+      output[12 + outputOffset] = (intValue4 >>> 16) & mask;
+      output[13 + outputOffset] = ((intValue4 >>> 28) | (intValue5 << 4)) & mask;
+      output[14 + outputOffset] = (intValue5 >>> 8) & mask;
+      output[15 + outputOffset] = intValue5 >>> 20;
+      output[16 + outputOffset] = intValue6 & mask;
+      output[17 + outputOffset] = (intValue6 >>> 12) & mask;
+      output[18 + outputOffset] = ((intValue6 >>> 24) | (intValue7 << 8)) & mask;
+      output[19 + outputOffset] = (intValue7 >>> 4) & mask;
+      output[20 + outputOffset] = (intValue7 >>> 16) & mask;
+      output[21 + outputOffset] = ((intValue7 >>> 28) | (intValue8 << 4)) & mask;
+      output[22 + outputOffset] = (intValue8 >>> 8) & mask;
+      output[23 + outputOffset] = intValue8 >>> 20;
+      output[24 + outputOffset] = intValue9 & mask;
+      output[25 + outputOffset] = (intValue9 >>> 12) & mask;
+      output[26 + outputOffset] = ((intValue9 >>> 24) | (intValue10 << 8)) & mask;
+      output[27 + outputOffset] = (intValue10 >>> 4) & mask;
+      output[28 + outputOffset] = (intValue10 >>> 16) & mask;
+      output[29 + outputOffset] = ((intValue10 >>> 28) | (intValue11 << 4)) & mask;
+      output[30 + outputOffset] = (intValue11 >>> 8) & mask;
+      output[31 + outputOffset] = intValue11 >>> 20;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode13(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 13;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 13) & mask;
+      output[2 + outputOffset] = ((intValue0 >>> 26) | (intValue1 << 6)) & mask;
+      output[3 + outputOffset] = (intValue1 >>> 7) & mask;
+      output[4 + outputOffset] = ((intValue1 >>> 20) | (intValue2 << 12)) & mask;
+      output[5 + outputOffset] = (intValue2 >>> 1) & mask;
+      output[6 + outputOffset] = (intValue2 >>> 14) & mask;
+      output[7 + outputOffset] = ((intValue2 >>> 27) | (intValue3 << 5)) & mask;
+      output[8 + outputOffset] = (intValue3 >>> 8) & mask;
+      output[9 + outputOffset] = ((intValue3 >>> 21) | (intValue4 << 11)) & mask;
+      output[10 + outputOffset] = (intValue4 >>> 2) & mask;
+      output[11 + outputOffset] = (intValue4 >>> 15) & mask;
+      output[12 + outputOffset] = ((intValue4 >>> 28) | (intValue5 << 4)) & mask;
+      output[13 + outputOffset] = (intValue5 >>> 9) & mask;
+      output[14 + outputOffset] = ((intValue5 >>> 22) | (intValue6 << 10)) & mask;
+      output[15 + outputOffset] = (intValue6 >>> 3) & mask;
+      output[16 + outputOffset] = (intValue6 >>> 16) & mask;
+      output[17 + outputOffset] = ((intValue6 >>> 29) | (intValue7 << 3)) & mask;
+      output[18 + outputOffset] = (intValue7 >>> 10) & mask;
+      output[19 + outputOffset] = ((intValue7 >>> 23) | (intValue8 << 9)) & mask;
+      output[20 + outputOffset] = (intValue8 >>> 4) & mask;
+      output[21 + outputOffset] = (intValue8 >>> 17) & mask;
+      output[22 + outputOffset] = ((intValue8 >>> 30) | (intValue9 << 2)) & mask;
+      output[23 + outputOffset] = (intValue9 >>> 11) & mask;
+      output[24 + outputOffset] = ((intValue9 >>> 24) | (intValue10 << 8)) & mask;
+      output[25 + outputOffset] = (intValue10 >>> 5) & mask;
+      output[26 + outputOffset] = (intValue10 >>> 18) & mask;
+      output[27 + outputOffset] = ((intValue10 >>> 31) | (intValue11 << 1)) & mask;
+      output[28 + outputOffset] = (intValue11 >>> 12) & mask;
+      output[29 + outputOffset] = ((intValue11 >>> 25) | (intValue12 << 7)) & mask;
+      output[30 + outputOffset] = (intValue12 >>> 6) & mask;
+      output[31 + outputOffset] = intValue12 >>> 19;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode14(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 14;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 14) & mask;
+      output[2 + outputOffset] = ((intValue0 >>> 28) | (intValue1 << 4)) & mask;
+      output[3 + outputOffset] = (intValue1 >>> 10) & mask;
+      output[4 + outputOffset] = ((intValue1 >>> 24) | (intValue2 << 8)) & mask;
+      output[5 + outputOffset] = (intValue2 >>> 6) & mask;
+      output[6 + outputOffset] = ((intValue2 >>> 20) | (intValue3 << 12)) & mask;
+      output[7 + outputOffset] = (intValue3 >>> 2) & mask;
+      output[8 + outputOffset] = (intValue3 >>> 16) & mask;
+      output[9 + outputOffset] = ((intValue3 >>> 30) | (intValue4 << 2)) & mask;
+      output[10 + outputOffset] = (intValue4 >>> 12) & mask;
+      output[11 + outputOffset] = ((intValue4 >>> 26) | (intValue5 << 6)) & mask;
+      output[12 + outputOffset] = (intValue5 >>> 8) & mask;
+      output[13 + outputOffset] = ((intValue5 >>> 22) | (intValue6 << 10)) & mask;
+      output[14 + outputOffset] = (intValue6 >>> 4) & mask;
+      output[15 + outputOffset] = intValue6 >>> 18;
+      output[16 + outputOffset] = intValue7 & mask;
+      output[17 + outputOffset] = (intValue7 >>> 14) & mask;
+      output[18 + outputOffset] = ((intValue7 >>> 28) | (intValue8 << 4)) & mask;
+      output[19 + outputOffset] = (intValue8 >>> 10) & mask;
+      output[20 + outputOffset] = ((intValue8 >>> 24) | (intValue9 << 8)) & mask;
+      output[21 + outputOffset] = (intValue9 >>> 6) & mask;
+      output[22 + outputOffset] = ((intValue9 >>> 20) | (intValue10 << 12)) & mask;
+      output[23 + outputOffset] = (intValue10 >>> 2) & mask;
+      output[24 + outputOffset] = (intValue10 >>> 16) & mask;
+      output[25 + outputOffset] = ((intValue10 >>> 30) | (intValue11 << 2)) & mask;
+      output[26 + outputOffset] = (intValue11 >>> 12) & mask;
+      output[27 + outputOffset] = ((intValue11 >>> 26) | (intValue12 << 6)) & mask;
+      output[28 + outputOffset] = (intValue12 >>> 8) & mask;
+      output[29 + outputOffset] = ((intValue12 >>> 22) | (intValue13 << 10)) & mask;
+      output[30 + outputOffset] = (intValue13 >>> 4) & mask;
+      output[31 + outputOffset] = intValue13 >>> 18;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode15(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 15;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = (intValue0 >>> 15) & mask;
+      output[2 + outputOffset] = ((intValue0 >>> 30) | (intValue1 << 2)) & mask;
+      output[3 + outputOffset] = (intValue1 >>> 13) & mask;
+      output[4 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[5 + outputOffset] = (intValue2 >>> 11) & mask;
+      output[6 + outputOffset] = ((intValue2 >>> 26) | (intValue3 << 6)) & mask;
+      output[7 + outputOffset] = (intValue3 >>> 9) & mask;
+      output[8 + outputOffset] = ((intValue3 >>> 24) | (intValue4 << 8)) & mask;
+      output[9 + outputOffset] = (intValue4 >>> 7) & mask;
+      output[10 + outputOffset] = ((intValue4 >>> 22) | (intValue5 << 10)) & mask;
+      output[11 + outputOffset] = (intValue5 >>> 5) & mask;
+      output[12 + outputOffset] = ((intValue5 >>> 20) | (intValue6 << 12)) & mask;
+      output[13 + outputOffset] = (intValue6 >>> 3) & mask;
+      output[14 + outputOffset] = ((intValue6 >>> 18) | (intValue7 << 14)) & mask;
+      output[15 + outputOffset] = (intValue7 >>> 1) & mask;
+      output[16 + outputOffset] = (intValue7 >>> 16) & mask;
+      output[17 + outputOffset] = ((intValue7 >>> 31) | (intValue8 << 1)) & mask;
+      output[18 + outputOffset] = (intValue8 >>> 14) & mask;
+      output[19 + outputOffset] = ((intValue8 >>> 29) | (intValue9 << 3)) & mask;
+      output[20 + outputOffset] = (intValue9 >>> 12) & mask;
+      output[21 + outputOffset] = ((intValue9 >>> 27) | (intValue10 << 5)) & mask;
+      output[22 + outputOffset] = (intValue10 >>> 10) & mask;
+      output[23 + outputOffset] = ((intValue10 >>> 25) | (intValue11 << 7)) & mask;
+      output[24 + outputOffset] = (intValue11 >>> 8) & mask;
+      output[25 + outputOffset] = ((intValue11 >>> 23) | (intValue12 << 9)) & mask;
+      output[26 + outputOffset] = (intValue12 >>> 6) & mask;
+      output[27 + outputOffset] = ((intValue12 >>> 21) | (intValue13 << 11)) & mask;
+      output[28 + outputOffset] = (intValue13 >>> 4) & mask;
+      output[29 + outputOffset] = ((intValue13 >>> 19) | (intValue14 << 13)) & mask;
+      output[30 + outputOffset] = (intValue14 >>> 2) & mask;
+      output[31 + outputOffset] = intValue14 >>> 17;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode16(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 16;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = intValue0 >>> 16;
+      output[2 + outputOffset] = intValue1 & mask;
+      output[3 + outputOffset] = intValue1 >>> 16;
+      output[4 + outputOffset] = intValue2 & mask;
+      output[5 + outputOffset] = intValue2 >>> 16;
+      output[6 + outputOffset] = intValue3 & mask;
+      output[7 + outputOffset] = intValue3 >>> 16;
+      output[8 + outputOffset] = intValue4 & mask;
+      output[9 + outputOffset] = intValue4 >>> 16;
+      output[10 + outputOffset] = intValue5 & mask;
+      output[11 + outputOffset] = intValue5 >>> 16;
+      output[12 + outputOffset] = intValue6 & mask;
+      output[13 + outputOffset] = intValue6 >>> 16;
+      output[14 + outputOffset] = intValue7 & mask;
+      output[15 + outputOffset] = intValue7 >>> 16;
+      output[16 + outputOffset] = intValue8 & mask;
+      output[17 + outputOffset] = intValue8 >>> 16;
+      output[18 + outputOffset] = intValue9 & mask;
+      output[19 + outputOffset] = intValue9 >>> 16;
+      output[20 + outputOffset] = intValue10 & mask;
+      output[21 + outputOffset] = intValue10 >>> 16;
+      output[22 + outputOffset] = intValue11 & mask;
+      output[23 + outputOffset] = intValue11 >>> 16;
+      output[24 + outputOffset] = intValue12 & mask;
+      output[25 + outputOffset] = intValue12 >>> 16;
+      output[26 + outputOffset] = intValue13 & mask;
+      output[27 + outputOffset] = intValue13 >>> 16;
+      output[28 + outputOffset] = intValue14 & mask;
+      output[29 + outputOffset] = intValue14 >>> 16;
+      output[30 + outputOffset] = intValue15 & mask;
+      output[31 + outputOffset] = intValue15 >>> 16;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode17(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 17;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 17) | (intValue1 << 15)) & mask;
+      output[2 + outputOffset] = (intValue1 >>> 2) & mask;
+      output[3 + outputOffset] = ((intValue1 >>> 19) | (intValue2 << 13)) & mask;
+      output[4 + outputOffset] = (intValue2 >>> 4) & mask;
+      output[5 + outputOffset] = ((intValue2 >>> 21) | (intValue3 << 11)) & mask;
+      output[6 + outputOffset] = (intValue3 >>> 6) & mask;
+      output[7 + outputOffset] = ((intValue3 >>> 23) | (intValue4 << 9)) & mask;
+      output[8 + outputOffset] = (intValue4 >>> 8) & mask;
+      output[9 + outputOffset] = ((intValue4 >>> 25) | (intValue5 << 7)) & mask;
+      output[10 + outputOffset] = (intValue5 >>> 10) & mask;
+      output[11 + outputOffset] = ((intValue5 >>> 27) | (intValue6 << 5)) & mask;
+      output[12 + outputOffset] = (intValue6 >>> 12) & mask;
+      output[13 + outputOffset] = ((intValue6 >>> 29) | (intValue7 << 3)) & mask;
+      output[14 + outputOffset] = (intValue7 >>> 14) & mask;
+      output[15 + outputOffset] = ((intValue7 >>> 31) | (intValue8 << 1)) & mask;
+      output[16 + outputOffset] = ((intValue8 >>> 16) | (intValue9 << 16)) & mask;
+      output[17 + outputOffset] = (intValue9 >>> 1) & mask;
+      output[18 + outputOffset] = ((intValue9 >>> 18) | (intValue10 << 14)) & mask;
+      output[19 + outputOffset] = (intValue10 >>> 3) & mask;
+      output[20 + outputOffset] = ((intValue10 >>> 20) | (intValue11 << 12)) & mask;
+      output[21 + outputOffset] = (intValue11 >>> 5) & mask;
+      output[22 + outputOffset] = ((intValue11 >>> 22) | (intValue12 << 10)) & mask;
+      output[23 + outputOffset] = (intValue12 >>> 7) & mask;
+      output[24 + outputOffset] = ((intValue12 >>> 24) | (intValue13 << 8)) & mask;
+      output[25 + outputOffset] = (intValue13 >>> 9) & mask;
+      output[26 + outputOffset] = ((intValue13 >>> 26) | (intValue14 << 6)) & mask;
+      output[27 + outputOffset] = (intValue14 >>> 11) & mask;
+      output[28 + outputOffset] = ((intValue14 >>> 28) | (intValue15 << 4)) & mask;
+      output[29 + outputOffset] = (intValue15 >>> 13) & mask;
+      output[30 + outputOffset] = ((intValue15 >>> 30) | (intValue16 << 2)) & mask;
+      output[31 + outputOffset] = intValue16 >>> 15;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode18(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 18;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 18) | (intValue1 << 14)) & mask;
+      output[2 + outputOffset] = (intValue1 >>> 4) & mask;
+      output[3 + outputOffset] = ((intValue1 >>> 22) | (intValue2 << 10)) & mask;
+      output[4 + outputOffset] = (intValue2 >>> 8) & mask;
+      output[5 + outputOffset] = ((intValue2 >>> 26) | (intValue3 << 6)) & mask;
+      output[6 + outputOffset] = (intValue3 >>> 12) & mask;
+      output[7 + outputOffset] = ((intValue3 >>> 30) | (intValue4 << 2)) & mask;
+      output[8 + outputOffset] = ((intValue4 >>> 16) | (intValue5 << 16)) & mask;
+      output[9 + outputOffset] = (intValue5 >>> 2) & mask;
+      output[10 + outputOffset] = ((intValue5 >>> 20) | (intValue6 << 12)) & mask;
+      output[11 + outputOffset] = (intValue6 >>> 6) & mask;
+      output[12 + outputOffset] = ((intValue6 >>> 24) | (intValue7 << 8)) & mask;
+      output[13 + outputOffset] = (intValue7 >>> 10) & mask;
+      output[14 + outputOffset] = ((intValue7 >>> 28) | (intValue8 << 4)) & mask;
+      output[15 + outputOffset] = intValue8 >>> 14;
+      output[16 + outputOffset] = intValue9 & mask;
+      output[17 + outputOffset] = ((intValue9 >>> 18) | (intValue10 << 14)) & mask;
+      output[18 + outputOffset] = (intValue10 >>> 4) & mask;
+      output[19 + outputOffset] = ((intValue10 >>> 22) | (intValue11 << 10)) & mask;
+      output[20 + outputOffset] = (intValue11 >>> 8) & mask;
+      output[21 + outputOffset] = ((intValue11 >>> 26) | (intValue12 << 6)) & mask;
+      output[22 + outputOffset] = (intValue12 >>> 12) & mask;
+      output[23 + outputOffset] = ((intValue12 >>> 30) | (intValue13 << 2)) & mask;
+      output[24 + outputOffset] = ((intValue13 >>> 16) | (intValue14 << 16)) & mask;
+      output[25 + outputOffset] = (intValue14 >>> 2) & mask;
+      output[26 + outputOffset] = ((intValue14 >>> 20) | (intValue15 << 12)) & mask;
+      output[27 + outputOffset] = (intValue15 >>> 6) & mask;
+      output[28 + outputOffset] = ((intValue15 >>> 24) | (intValue16 << 8)) & mask;
+      output[29 + outputOffset] = (intValue16 >>> 10) & mask;
+      output[30 + outputOffset] = ((intValue16 >>> 28) | (intValue17 << 4)) & mask;
+      output[31 + outputOffset] = intValue17 >>> 14;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode19(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 19;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 19) | (intValue1 << 13)) & mask;
+      output[2 + outputOffset] = (intValue1 >>> 6) & mask;
+      output[3 + outputOffset] = ((intValue1 >>> 25) | (intValue2 << 7)) & mask;
+      output[4 + outputOffset] = (intValue2 >>> 12) & mask;
+      output[5 + outputOffset] = ((intValue2 >>> 31) | (intValue3 << 1)) & mask;
+      output[6 + outputOffset] = ((intValue3 >>> 18) | (intValue4 << 14)) & mask;
+      output[7 + outputOffset] = (intValue4 >>> 5) & mask;
+      output[8 + outputOffset] = ((intValue4 >>> 24) | (intValue5 << 8)) & mask;
+      output[9 + outputOffset] = (intValue5 >>> 11) & mask;
+      output[10 + outputOffset] = ((intValue5 >>> 30) | (intValue6 << 2)) & mask;
+      output[11 + outputOffset] = ((intValue6 >>> 17) | (intValue7 << 15)) & mask;
+      output[12 + outputOffset] = (intValue7 >>> 4) & mask;
+      output[13 + outputOffset] = ((intValue7 >>> 23) | (intValue8 << 9)) & mask;
+      output[14 + outputOffset] = (intValue8 >>> 10) & mask;
+      output[15 + outputOffset] = ((intValue8 >>> 29) | (intValue9 << 3)) & mask;
+      output[16 + outputOffset] = ((intValue9 >>> 16) | (intValue10 << 16)) & mask;
+      output[17 + outputOffset] = (intValue10 >>> 3) & mask;
+      output[18 + outputOffset] = ((intValue10 >>> 22) | (intValue11 << 10)) & mask;
+      output[19 + outputOffset] = (intValue11 >>> 9) & mask;
+      output[20 + outputOffset] = ((intValue11 >>> 28) | (intValue12 << 4)) & mask;
+      output[21 + outputOffset] = ((intValue12 >>> 15) | (intValue13 << 17)) & mask;
+      output[22 + outputOffset] = (intValue13 >>> 2) & mask;
+      output[23 + outputOffset] = ((intValue13 >>> 21) | (intValue14 << 11)) & mask;
+      output[24 + outputOffset] = (intValue14 >>> 8) & mask;
+      output[25 + outputOffset] = ((intValue14 >>> 27) | (intValue15 << 5)) & mask;
+      output[26 + outputOffset] = ((intValue15 >>> 14) | (intValue16 << 18)) & mask;
+      output[27 + outputOffset] = (intValue16 >>> 1) & mask;
+      output[28 + outputOffset] = ((intValue16 >>> 20) | (intValue17 << 12)) & mask;
+      output[29 + outputOffset] = (intValue17 >>> 7) & mask;
+      output[30 + outputOffset] = ((intValue17 >>> 26) | (intValue18 << 6)) & mask;
+      output[31 + outputOffset] = intValue18 >>> 13;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode20(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 20;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 20) | (intValue1 << 12)) & mask;
+      output[2 + outputOffset] = (intValue1 >>> 8) & mask;
+      output[3 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[4 + outputOffset] = ((intValue2 >>> 16) | (intValue3 << 16)) & mask;
+      output[5 + outputOffset] = (intValue3 >>> 4) & mask;
+      output[6 + outputOffset] = ((intValue3 >>> 24) | (intValue4 << 8)) & mask;
+      output[7 + outputOffset] = intValue4 >>> 12;
+      output[8 + outputOffset] = intValue5 & mask;
+      output[9 + outputOffset] = ((intValue5 >>> 20) | (intValue6 << 12)) & mask;
+      output[10 + outputOffset] = (intValue6 >>> 8) & mask;
+      output[11 + outputOffset] = ((intValue6 >>> 28) | (intValue7 << 4)) & mask;
+      output[12 + outputOffset] = ((intValue7 >>> 16) | (intValue8 << 16)) & mask;
+      output[13 + outputOffset] = (intValue8 >>> 4) & mask;
+      output[14 + outputOffset] = ((intValue8 >>> 24) | (intValue9 << 8)) & mask;
+      output[15 + outputOffset] = intValue9 >>> 12;
+      output[16 + outputOffset] = intValue10 & mask;
+      output[17 + outputOffset] = ((intValue10 >>> 20) | (intValue11 << 12)) & mask;
+      output[18 + outputOffset] = (intValue11 >>> 8) & mask;
+      output[19 + outputOffset] = ((intValue11 >>> 28) | (intValue12 << 4)) & mask;
+      output[20 + outputOffset] = ((intValue12 >>> 16) | (intValue13 << 16)) & mask;
+      output[21 + outputOffset] = (intValue13 >>> 4) & mask;
+      output[22 + outputOffset] = ((intValue13 >>> 24) | (intValue14 << 8)) & mask;
+      output[23 + outputOffset] = intValue14 >>> 12;
+      output[24 + outputOffset] = intValue15 & mask;
+      output[25 + outputOffset] = ((intValue15 >>> 20) | (intValue16 << 12)) & mask;
+      output[26 + outputOffset] = (intValue16 >>> 8) & mask;
+      output[27 + outputOffset] = ((intValue16 >>> 28) | (intValue17 << 4)) & mask;
+      output[28 + outputOffset] = ((intValue17 >>> 16) | (intValue18 << 16)) & mask;
+      output[29 + outputOffset] = (intValue18 >>> 4) & mask;
+      output[30 + outputOffset] = ((intValue18 >>> 24) | (intValue19 << 8)) & mask;
+      output[31 + outputOffset] = intValue19 >>> 12;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode21(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 21;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 21) | (intValue1 << 11)) & mask;
+      output[2 + outputOffset] = (intValue1 >>> 10) & mask;
+      output[3 + outputOffset] = ((intValue1 >>> 31) | (intValue2 << 1)) & mask;
+      output[4 + outputOffset] = ((intValue2 >>> 20) | (intValue3 << 12)) & mask;
+      output[5 + outputOffset] = (intValue3 >>> 9) & mask;
+      output[6 + outputOffset] = ((intValue3 >>> 30) | (intValue4 << 2)) & mask;
+      output[7 + outputOffset] = ((intValue4 >>> 19) | (intValue5 << 13)) & mask;
+      output[8 + outputOffset] = (intValue5 >>> 8) & mask;
+      output[9 + outputOffset] = ((intValue5 >>> 29) | (intValue6 << 3)) & mask;
+      output[10 + outputOffset] = ((intValue6 >>> 18) | (intValue7 << 14)) & mask;
+      output[11 + outputOffset] = (intValue7 >>> 7) & mask;
+      output[12 + outputOffset] = ((intValue7 >>> 28) | (intValue8 << 4)) & mask;
+      output[13 + outputOffset] = ((intValue8 >>> 17) | (intValue9 << 15)) & mask;
+      output[14 + outputOffset] = (intValue9 >>> 6) & mask;
+      output[15 + outputOffset] = ((intValue9 >>> 27) | (intValue10 << 5)) & mask;
+      output[16 + outputOffset] = ((intValue10 >>> 16) | (intValue11 << 16)) & mask;
+      output[17 + outputOffset] = (intValue11 >>> 5) & mask;
+      output[18 + outputOffset] = ((intValue11 >>> 26) | (intValue12 << 6)) & mask;
+      output[19 + outputOffset] = ((intValue12 >>> 15) | (intValue13 << 17)) & mask;
+      output[20 + outputOffset] = (intValue13 >>> 4) & mask;
+      output[21 + outputOffset] = ((intValue13 >>> 25) | (intValue14 << 7)) & mask;
+      output[22 + outputOffset] = ((intValue14 >>> 14) | (intValue15 << 18)) & mask;
+      output[23 + outputOffset] = (intValue15 >>> 3) & mask;
+      output[24 + outputOffset] = ((intValue15 >>> 24) | (intValue16 << 8)) & mask;
+      output[25 + outputOffset] = ((intValue16 >>> 13) | (intValue17 << 19)) & mask;
+      output[26 + outputOffset] = (intValue17 >>> 2) & mask;
+      output[27 + outputOffset] = ((intValue17 >>> 23) | (intValue18 << 9)) & mask;
+      output[28 + outputOffset] = ((intValue18 >>> 12) | (intValue19 << 20)) & mask;
+      output[29 + outputOffset] = (intValue19 >>> 1) & mask;
+      output[30 + outputOffset] = ((intValue19 >>> 22) | (intValue20 << 10)) & mask;
+      output[31 + outputOffset] = intValue20 >>> 11;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode22(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 22;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 22) | (intValue1 << 10)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 12) | (intValue2 << 20)) & mask;
+      output[3 + outputOffset] = (intValue2 >>> 2) & mask;
+      output[4 + outputOffset] = ((intValue2 >>> 24) | (intValue3 << 8)) & mask;
+      output[5 + outputOffset] = ((intValue3 >>> 14) | (intValue4 << 18)) & mask;
+      output[6 + outputOffset] = (intValue4 >>> 4) & mask;
+      output[7 + outputOffset] = ((intValue4 >>> 26) | (intValue5 << 6)) & mask;
+      output[8 + outputOffset] = ((intValue5 >>> 16) | (intValue6 << 16)) & mask;
+      output[9 + outputOffset] = (intValue6 >>> 6) & mask;
+      output[10 + outputOffset] = ((intValue6 >>> 28) | (intValue7 << 4)) & mask;
+      output[11 + outputOffset] = ((intValue7 >>> 18) | (intValue8 << 14)) & mask;
+      output[12 + outputOffset] = (intValue8 >>> 8) & mask;
+      output[13 + outputOffset] = ((intValue8 >>> 30) | (intValue9 << 2)) & mask;
+      output[14 + outputOffset] = ((intValue9 >>> 20) | (intValue10 << 12)) & mask;
+      output[15 + outputOffset] = intValue10 >>> 10;
+      output[16 + outputOffset] = intValue11 & mask;
+      output[17 + outputOffset] = ((intValue11 >>> 22) | (intValue12 << 10)) & mask;
+      output[18 + outputOffset] = ((intValue12 >>> 12) | (intValue13 << 20)) & mask;
+      output[19 + outputOffset] = (intValue13 >>> 2) & mask;
+      output[20 + outputOffset] = ((intValue13 >>> 24) | (intValue14 << 8)) & mask;
+      output[21 + outputOffset] = ((intValue14 >>> 14) | (intValue15 << 18)) & mask;
+      output[22 + outputOffset] = (intValue15 >>> 4) & mask;
+      output[23 + outputOffset] = ((intValue15 >>> 26) | (intValue16 << 6)) & mask;
+      output[24 + outputOffset] = ((intValue16 >>> 16) | (intValue17 << 16)) & mask;
+      output[25 + outputOffset] = (intValue17 >>> 6) & mask;
+      output[26 + outputOffset] = ((intValue17 >>> 28) | (intValue18 << 4)) & mask;
+      output[27 + outputOffset] = ((intValue18 >>> 18) | (intValue19 << 14)) & mask;
+      output[28 + outputOffset] = (intValue19 >>> 8) & mask;
+      output[29 + outputOffset] = ((intValue19 >>> 30) | (intValue20 << 2)) & mask;
+      output[30 + outputOffset] = ((intValue20 >>> 20) | (intValue21 << 12)) & mask;
+      output[31 + outputOffset] = intValue21 >>> 10;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode23(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 23;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 23) | (intValue1 << 9)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 14) | (intValue2 << 18)) & mask;
+      output[3 + outputOffset] = (intValue2 >>> 5) & mask;
+      output[4 + outputOffset] = ((intValue2 >>> 28) | (intValue3 << 4)) & mask;
+      output[5 + outputOffset] = ((intValue3 >>> 19) | (intValue4 << 13)) & mask;
+      output[6 + outputOffset] = ((intValue4 >>> 10) | (intValue5 << 22)) & mask;
+      output[7 + outputOffset] = (intValue5 >>> 1) & mask;
+      output[8 + outputOffset] = ((intValue5 >>> 24) | (intValue6 << 8)) & mask;
+      output[9 + outputOffset] = ((intValue6 >>> 15) | (intValue7 << 17)) & mask;
+      output[10 + outputOffset] = (intValue7 >>> 6) & mask;
+      output[11 + outputOffset] = ((intValue7 >>> 29) | (intValue8 << 3)) & mask;
+      output[12 + outputOffset] = ((intValue8 >>> 20) | (intValue9 << 12)) & mask;
+      output[13 + outputOffset] = ((intValue9 >>> 11) | (intValue10 << 21)) & mask;
+      output[14 + outputOffset] = (intValue10 >>> 2) & mask;
+      output[15 + outputOffset] = ((intValue10 >>> 25) | (intValue11 << 7)) & mask;
+      output[16 + outputOffset] = ((intValue11 >>> 16) | (intValue12 << 16)) & mask;
+      output[17 + outputOffset] = (intValue12 >>> 7) & mask;
+      output[18 + outputOffset] = ((intValue12 >>> 30) | (intValue13 << 2)) & mask;
+      output[19 + outputOffset] = ((intValue13 >>> 21) | (intValue14 << 11)) & mask;
+      output[20 + outputOffset] = ((intValue14 >>> 12) | (intValue15 << 20)) & mask;
+      output[21 + outputOffset] = (intValue15 >>> 3) & mask;
+      output[22 + outputOffset] = ((intValue15 >>> 26) | (intValue16 << 6)) & mask;
+      output[23 + outputOffset] = ((intValue16 >>> 17) | (intValue17 << 15)) & mask;
+      output[24 + outputOffset] = (intValue17 >>> 8) & mask;
+      output[25 + outputOffset] = ((intValue17 >>> 31) | (intValue18 << 1)) & mask;
+      output[26 + outputOffset] = ((intValue18 >>> 22) | (intValue19 << 10)) & mask;
+      output[27 + outputOffset] = ((intValue19 >>> 13) | (intValue20 << 19)) & mask;
+      output[28 + outputOffset] = (intValue20 >>> 4) & mask;
+      output[29 + outputOffset] = ((intValue20 >>> 27) | (intValue21 << 5)) & mask;
+      output[30 + outputOffset] = ((intValue21 >>> 18) | (intValue22 << 14)) & mask;
+      output[31 + outputOffset] = intValue22 >>> 9;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode24(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 24;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 24) | (intValue1 << 8)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 16) | (intValue2 << 16)) & mask;
+      output[3 + outputOffset] = intValue2 >>> 8;
+      output[4 + outputOffset] = intValue3 & mask;
+      output[5 + outputOffset] = ((intValue3 >>> 24) | (intValue4 << 8)) & mask;
+      output[6 + outputOffset] = ((intValue4 >>> 16) | (intValue5 << 16)) & mask;
+      output[7 + outputOffset] = intValue5 >>> 8;
+      output[8 + outputOffset] = intValue6 & mask;
+      output[9 + outputOffset] = ((intValue6 >>> 24) | (intValue7 << 8)) & mask;
+      output[10 + outputOffset] = ((intValue7 >>> 16) | (intValue8 << 16)) & mask;
+      output[11 + outputOffset] = intValue8 >>> 8;
+      output[12 + outputOffset] = intValue9 & mask;
+      output[13 + outputOffset] = ((intValue9 >>> 24) | (intValue10 << 8)) & mask;
+      output[14 + outputOffset] = ((intValue10 >>> 16) | (intValue11 << 16)) & mask;
+      output[15 + outputOffset] = intValue11 >>> 8;
+      output[16 + outputOffset] = intValue12 & mask;
+      output[17 + outputOffset] = ((intValue12 >>> 24) | (intValue13 << 8)) & mask;
+      output[18 + outputOffset] = ((intValue13 >>> 16) | (intValue14 << 16)) & mask;
+      output[19 + outputOffset] = intValue14 >>> 8;
+      output[20 + outputOffset] = intValue15 & mask;
+      output[21 + outputOffset] = ((intValue15 >>> 24) | (intValue16 << 8)) & mask;
+      output[22 + outputOffset] = ((intValue16 >>> 16) | (intValue17 << 16)) & mask;
+      output[23 + outputOffset] = intValue17 >>> 8;
+      output[24 + outputOffset] = intValue18 & mask;
+      output[25 + outputOffset] = ((intValue18 >>> 24) | (intValue19 << 8)) & mask;
+      output[26 + outputOffset] = ((intValue19 >>> 16) | (intValue20 << 16)) & mask;
+      output[27 + outputOffset] = intValue20 >>> 8;
+      output[28 + outputOffset] = intValue21 & mask;
+      output[29 + outputOffset] = ((intValue21 >>> 24) | (intValue22 << 8)) & mask;
+      output[30 + outputOffset] = ((intValue22 >>> 16) | (intValue23 << 16)) & mask;
+      output[31 + outputOffset] = intValue23 >>> 8;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode25(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 25;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 25) | (intValue1 << 7)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 18) | (intValue2 << 14)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 11) | (intValue3 << 21)) & mask;
+      output[4 + outputOffset] = (intValue3 >>> 4) & mask;
+      output[5 + outputOffset] = ((intValue3 >>> 29) | (intValue4 << 3)) & mask;
+      output[6 + outputOffset] = ((intValue4 >>> 22) | (intValue5 << 10)) & mask;
+      output[7 + outputOffset] = ((intValue5 >>> 15) | (intValue6 << 17)) & mask;
+      output[8 + outputOffset] = ((intValue6 >>> 8) | (intValue7 << 24)) & mask;
+      output[9 + outputOffset] = (intValue7 >>> 1) & mask;
+      output[10 + outputOffset] = ((intValue7 >>> 26) | (intValue8 << 6)) & mask;
+      output[11 + outputOffset] = ((intValue8 >>> 19) | (intValue9 << 13)) & mask;
+      output[12 + outputOffset] = ((intValue9 >>> 12) | (intValue10 << 20)) & mask;
+      output[13 + outputOffset] = (intValue10 >>> 5) & mask;
+      output[14 + outputOffset] = ((intValue10 >>> 30) | (intValue11 << 2)) & mask;
+      output[15 + outputOffset] = ((intValue11 >>> 23) | (intValue12 << 9)) & mask;
+      output[16 + outputOffset] = ((intValue12 >>> 16) | (intValue13 << 16)) & mask;
+      output[17 + outputOffset] = ((intValue13 >>> 9) | (intValue14 << 23)) & mask;
+      output[18 + outputOffset] = (intValue14 >>> 2) & mask;
+      output[19 + outputOffset] = ((intValue14 >>> 27) | (intValue15 << 5)) & mask;
+      output[20 + outputOffset] = ((intValue15 >>> 20) | (intValue16 << 12)) & mask;
+      output[21 + outputOffset] = ((intValue16 >>> 13) | (intValue17 << 19)) & mask;
+      output[22 + outputOffset] = (intValue17 >>> 6) & mask;
+      output[23 + outputOffset] = ((intValue17 >>> 31) | (intValue18 << 1)) & mask;
+      output[24 + outputOffset] = ((intValue18 >>> 24) | (intValue19 << 8)) & mask;
+      output[25 + outputOffset] = ((intValue19 >>> 17) | (intValue20 << 15)) & mask;
+      output[26 + outputOffset] = ((intValue20 >>> 10) | (intValue21 << 22)) & mask;
+      output[27 + outputOffset] = (intValue21 >>> 3) & mask;
+      output[28 + outputOffset] = ((intValue21 >>> 28) | (intValue22 << 4)) & mask;
+      output[29 + outputOffset] = ((intValue22 >>> 21) | (intValue23 << 11)) & mask;
+      output[30 + outputOffset] = ((intValue23 >>> 14) | (intValue24 << 18)) & mask;
+      output[31 + outputOffset] = intValue24 >>> 7;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode26(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 26;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 26) | (intValue1 << 6)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 20) | (intValue2 << 12)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 14) | (intValue3 << 18)) & mask;
+      output[4 + outputOffset] = ((intValue3 >>> 8) | (intValue4 << 24)) & mask;
+      output[5 + outputOffset] = (intValue4 >>> 2) & mask;
+      output[6 + outputOffset] = ((intValue4 >>> 28) | (intValue5 << 4)) & mask;
+      output[7 + outputOffset] = ((intValue5 >>> 22) | (intValue6 << 10)) & mask;
+      output[8 + outputOffset] = ((intValue6 >>> 16) | (intValue7 << 16)) & mask;
+      output[9 + outputOffset] = ((intValue7 >>> 10) | (intValue8 << 22)) & mask;
+      output[10 + outputOffset] = (intValue8 >>> 4) & mask;
+      output[11 + outputOffset] = ((intValue8 >>> 30) | (intValue9 << 2)) & mask;
+      output[12 + outputOffset] = ((intValue9 >>> 24) | (intValue10 << 8)) & mask;
+      output[13 + outputOffset] = ((intValue10 >>> 18) | (intValue11 << 14)) & mask;
+      output[14 + outputOffset] = ((intValue11 >>> 12) | (intValue12 << 20)) & mask;
+      output[15 + outputOffset] = intValue12 >>> 6;
+      output[16 + outputOffset] = intValue13 & mask;
+      output[17 + outputOffset] = ((intValue13 >>> 26) | (intValue14 << 6)) & mask;
+      output[18 + outputOffset] = ((intValue14 >>> 20) | (intValue15 << 12)) & mask;
+      output[19 + outputOffset] = ((intValue15 >>> 14) | (intValue16 << 18)) & mask;
+      output[20 + outputOffset] = ((intValue16 >>> 8) | (intValue17 << 24)) & mask;
+      output[21 + outputOffset] = (intValue17 >>> 2) & mask;
+      output[22 + outputOffset] = ((intValue17 >>> 28) | (intValue18 << 4)) & mask;
+      output[23 + outputOffset] = ((intValue18 >>> 22) | (intValue19 << 10)) & mask;
+      output[24 + outputOffset] = ((intValue19 >>> 16) | (intValue20 << 16)) & mask;
+      output[25 + outputOffset] = ((intValue20 >>> 10) | (intValue21 << 22)) & mask;
+      output[26 + outputOffset] = (intValue21 >>> 4) & mask;
+      output[27 + outputOffset] = ((intValue21 >>> 30) | (intValue22 << 2)) & mask;
+      output[28 + outputOffset] = ((intValue22 >>> 24) | (intValue23 << 8)) & mask;
+      output[29 + outputOffset] = ((intValue23 >>> 18) | (intValue24 << 14)) & mask;
+      output[30 + outputOffset] = ((intValue24 >>> 12) | (intValue25 << 20)) & mask;
+      output[31 + outputOffset] = intValue25 >>> 6;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode27(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 27;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      int intValue26 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 27) | (intValue1 << 5)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 22) | (intValue2 << 10)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 17) | (intValue3 << 15)) & mask;
+      output[4 + outputOffset] = ((intValue3 >>> 12) | (intValue4 << 20)) & mask;
+      output[5 + outputOffset] = ((intValue4 >>> 7) | (intValue5 << 25)) & mask;
+      output[6 + outputOffset] = (intValue5 >>> 2) & mask;
+      output[7 + outputOffset] = ((intValue5 >>> 29) | (intValue6 << 3)) & mask;
+      output[8 + outputOffset] = ((intValue6 >>> 24) | (intValue7 << 8)) & mask;
+      output[9 + outputOffset] = ((intValue7 >>> 19) | (intValue8 << 13)) & mask;
+      output[10 + outputOffset] = ((intValue8 >>> 14) | (intValue9 << 18)) & mask;
+      output[11 + outputOffset] = ((intValue9 >>> 9) | (intValue10 << 23)) & mask;
+      output[12 + outputOffset] = (intValue10 >>> 4) & mask;
+      output[13 + outputOffset] = ((intValue10 >>> 31) | (intValue11 << 1)) & mask;
+      output[14 + outputOffset] = ((intValue11 >>> 26) | (intValue12 << 6)) & mask;
+      output[15 + outputOffset] = ((intValue12 >>> 21) | (intValue13 << 11)) & mask;
+      output[16 + outputOffset] = ((intValue13 >>> 16) | (intValue14 << 16)) & mask;
+      output[17 + outputOffset] = ((intValue14 >>> 11) | (intValue15 << 21)) & mask;
+      output[18 + outputOffset] = ((intValue15 >>> 6) | (intValue16 << 26)) & mask;
+      output[19 + outputOffset] = (intValue16 >>> 1) & mask;
+      output[20 + outputOffset] = ((intValue16 >>> 28) | (intValue17 << 4)) & mask;
+      output[21 + outputOffset] = ((intValue17 >>> 23) | (intValue18 << 9)) & mask;
+      output[22 + outputOffset] = ((intValue18 >>> 18) | (intValue19 << 14)) & mask;
+      output[23 + outputOffset] = ((intValue19 >>> 13) | (intValue20 << 19)) & mask;
+      output[24 + outputOffset] = ((intValue20 >>> 8) | (intValue21 << 24)) & mask;
+      output[25 + outputOffset] = (intValue21 >>> 3) & mask;
+      output[26 + outputOffset] = ((intValue21 >>> 30) | (intValue22 << 2)) & mask;
+      output[27 + outputOffset] = ((intValue22 >>> 25) | (intValue23 << 7)) & mask;
+      output[28 + outputOffset] = ((intValue23 >>> 20) | (intValue24 << 12)) & mask;
+      output[29 + outputOffset] = ((intValue24 >>> 15) | (intValue25 << 17)) & mask;
+      output[30 + outputOffset] = ((intValue25 >>> 10) | (intValue26 << 22)) & mask;
+      output[31 + outputOffset] = intValue26 >>> 5;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode28(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 28;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      int intValue26 = compressedBuffer.get();
+      int intValue27 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 28) | (intValue1 << 4)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 24) | (intValue2 << 8)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 20) | (intValue3 << 12)) & mask;
+      output[4 + outputOffset] = ((intValue3 >>> 16) | (intValue4 << 16)) & mask;
+      output[5 + outputOffset] = ((intValue4 >>> 12) | (intValue5 << 20)) & mask;
+      output[6 + outputOffset] = ((intValue5 >>> 8) | (intValue6 << 24)) & mask;
+      output[7 + outputOffset] = intValue6 >>> 4;
+      output[8 + outputOffset] = intValue7 & mask;
+      output[9 + outputOffset] = ((intValue7 >>> 28) | (intValue8 << 4)) & mask;
+      output[10 + outputOffset] = ((intValue8 >>> 24) | (intValue9 << 8)) & mask;
+      output[11 + outputOffset] = ((intValue9 >>> 20) | (intValue10 << 12)) & mask;
+      output[12 + outputOffset] = ((intValue10 >>> 16) | (intValue11 << 16)) & mask;
+      output[13 + outputOffset] = ((intValue11 >>> 12) | (intValue12 << 20)) & mask;
+      output[14 + outputOffset] = ((intValue12 >>> 8) | (intValue13 << 24)) & mask;
+      output[15 + outputOffset] = intValue13 >>> 4;
+      output[16 + outputOffset] = intValue14 & mask;
+      output[17 + outputOffset] = ((intValue14 >>> 28) | (intValue15 << 4)) & mask;
+      output[18 + outputOffset] = ((intValue15 >>> 24) | (intValue16 << 8)) & mask;
+      output[19 + outputOffset] = ((intValue16 >>> 20) | (intValue17 << 12)) & mask;
+      output[20 + outputOffset] = ((intValue17 >>> 16) | (intValue18 << 16)) & mask;
+      output[21 + outputOffset] = ((intValue18 >>> 12) | (intValue19 << 20)) & mask;
+      output[22 + outputOffset] = ((intValue19 >>> 8) | (intValue20 << 24)) & mask;
+      output[23 + outputOffset] = intValue20 >>> 4;
+      output[24 + outputOffset] = intValue21 & mask;
+      output[25 + outputOffset] = ((intValue21 >>> 28) | (intValue22 << 4)) & mask;
+      output[26 + outputOffset] = ((intValue22 >>> 24) | (intValue23 << 8)) & mask;
+      output[27 + outputOffset] = ((intValue23 >>> 20) | (intValue24 << 12)) & mask;
+      output[28 + outputOffset] = ((intValue24 >>> 16) | (intValue25 << 16)) & mask;
+      output[29 + outputOffset] = ((intValue25 >>> 12) | (intValue26 << 20)) & mask;
+      output[30 + outputOffset] = ((intValue26 >>> 8) | (intValue27 << 24)) & mask;
+      output[31 + outputOffset] = intValue27 >>> 4;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode29(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 29;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      int intValue26 = compressedBuffer.get();
+      int intValue27 = compressedBuffer.get();
+      int intValue28 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 29) | (intValue1 << 3)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 26) | (intValue2 << 6)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 23) | (intValue3 << 9)) & mask;
+      output[4 + outputOffset] = ((intValue3 >>> 20) | (intValue4 << 12)) & mask;
+      output[5 + outputOffset] = ((intValue4 >>> 17) | (intValue5 << 15)) & mask;
+      output[6 + outputOffset] = ((intValue5 >>> 14) | (intValue6 << 18)) & mask;
+      output[7 + outputOffset] = ((intValue6 >>> 11) | (intValue7 << 21)) & mask;
+      output[8 + outputOffset] = ((intValue7 >>> 8) | (intValue8 << 24)) & mask;
+      output[9 + outputOffset] = ((intValue8 >>> 5) | (intValue9 << 27)) & mask;
+      output[10 + outputOffset] = (intValue9 >>> 2) & mask;
+      output[11 + outputOffset] = ((intValue9 >>> 31) | (intValue10 << 1)) & mask;
+      output[12 + outputOffset] = ((intValue10 >>> 28) | (intValue11 << 4)) & mask;
+      output[13 + outputOffset] = ((intValue11 >>> 25) | (intValue12 << 7)) & mask;
+      output[14 + outputOffset] = ((intValue12 >>> 22) | (intValue13 << 10)) & mask;
+      output[15 + outputOffset] = ((intValue13 >>> 19) | (intValue14 << 13)) & mask;
+      output[16 + outputOffset] = ((intValue14 >>> 16) | (intValue15 << 16)) & mask;
+      output[17 + outputOffset] = ((intValue15 >>> 13) | (intValue16 << 19)) & mask;
+      output[18 + outputOffset] = ((intValue16 >>> 10) | (intValue17 << 22)) & mask;
+      output[19 + outputOffset] = ((intValue17 >>> 7) | (intValue18 << 25)) & mask;
+      output[20 + outputOffset] = ((intValue18 >>> 4) | (intValue19 << 28)) & mask;
+      output[21 + outputOffset] = (intValue19 >>> 1) & mask;
+      output[22 + outputOffset] = ((intValue19 >>> 30) | (intValue20 << 2)) & mask;
+      output[23 + outputOffset] = ((intValue20 >>> 27) | (intValue21 << 5)) & mask;
+      output[24 + outputOffset] = ((intValue21 >>> 24) | (intValue22 << 8)) & mask;
+      output[25 + outputOffset] = ((intValue22 >>> 21) | (intValue23 << 11)) & mask;
+      output[26 + outputOffset] = ((intValue23 >>> 18) | (intValue24 << 14)) & mask;
+      output[27 + outputOffset] = ((intValue24 >>> 15) | (intValue25 << 17)) & mask;
+      output[28 + outputOffset] = ((intValue25 >>> 12) | (intValue26 << 20)) & mask;
+      output[29 + outputOffset] = ((intValue26 >>> 9) | (intValue27 << 23)) & mask;
+      output[30 + outputOffset] = ((intValue27 >>> 6) | (intValue28 << 26)) & mask;
+      output[31 + outputOffset] = intValue28 >>> 3;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode30(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 30;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      int intValue26 = compressedBuffer.get();
+      int intValue27 = compressedBuffer.get();
+      int intValue28 = compressedBuffer.get();
+      int intValue29 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 30) | (intValue1 << 2)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 28) | (intValue2 << 4)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 26) | (intValue3 << 6)) & mask;
+      output[4 + outputOffset] = ((intValue3 >>> 24) | (intValue4 << 8)) & mask;
+      output[5 + outputOffset] = ((intValue4 >>> 22) | (intValue5 << 10)) & mask;
+      output[6 + outputOffset] = ((intValue5 >>> 20) | (intValue6 << 12)) & mask;
+      output[7 + outputOffset] = ((intValue6 >>> 18) | (intValue7 << 14)) & mask;
+      output[8 + outputOffset] = ((intValue7 >>> 16) | (intValue8 << 16)) & mask;
+      output[9 + outputOffset] = ((intValue8 >>> 14) | (intValue9 << 18)) & mask;
+      output[10 + outputOffset] = ((intValue9 >>> 12) | (intValue10 << 20)) & mask;
+      output[11 + outputOffset] = ((intValue10 >>> 10) | (intValue11 << 22)) & mask;
+      output[12 + outputOffset] = ((intValue11 >>> 8) | (intValue12 << 24)) & mask;
+      output[13 + outputOffset] = ((intValue12 >>> 6) | (intValue13 << 26)) & mask;
+      output[14 + outputOffset] = ((intValue13 >>> 4) | (intValue14 << 28)) & mask;
+      output[15 + outputOffset] = intValue14 >>> 2;
+      output[16 + outputOffset] = intValue15 & mask;
+      output[17 + outputOffset] = ((intValue15 >>> 30) | (intValue16 << 2)) & mask;
+      output[18 + outputOffset] = ((intValue16 >>> 28) | (intValue17 << 4)) & mask;
+      output[19 + outputOffset] = ((intValue17 >>> 26) | (intValue18 << 6)) & mask;
+      output[20 + outputOffset] = ((intValue18 >>> 24) | (intValue19 << 8)) & mask;
+      output[21 + outputOffset] = ((intValue19 >>> 22) | (intValue20 << 10)) & mask;
+      output[22 + outputOffset] = ((intValue20 >>> 20) | (intValue21 << 12)) & mask;
+      output[23 + outputOffset] = ((intValue21 >>> 18) | (intValue22 << 14)) & mask;
+      output[24 + outputOffset] = ((intValue22 >>> 16) | (intValue23 << 16)) & mask;
+      output[25 + outputOffset] = ((intValue23 >>> 14) | (intValue24 << 18)) & mask;
+      output[26 + outputOffset] = ((intValue24 >>> 12) | (intValue25 << 20)) & mask;
+      output[27 + outputOffset] = ((intValue25 >>> 10) | (intValue26 << 22)) & mask;
+      output[28 + outputOffset] = ((intValue26 >>> 8) | (intValue27 << 24)) & mask;
+      output[29 + outputOffset] = ((intValue27 >>> 6) | (intValue28 << 26)) & mask;
+      output[30 + outputOffset] = ((intValue28 >>> 4) | (intValue29 << 28)) & mask;
+      output[31 + outputOffset] = intValue29 >>> 2;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode31(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 31;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      int intValue26 = compressedBuffer.get();
+      int intValue27 = compressedBuffer.get();
+      int intValue28 = compressedBuffer.get();
+      int intValue29 = compressedBuffer.get();
+      int intValue30 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0 & mask;
+      output[1 + outputOffset] = ((intValue0 >>> 31) | (intValue1 << 1)) & mask;
+      output[2 + outputOffset] = ((intValue1 >>> 30) | (intValue2 << 2)) & mask;
+      output[3 + outputOffset] = ((intValue2 >>> 29) | (intValue3 << 3)) & mask;
+      output[4 + outputOffset] = ((intValue3 >>> 28) | (intValue4 << 4)) & mask;
+      output[5 + outputOffset] = ((intValue4 >>> 27) | (intValue5 << 5)) & mask;
+      output[6 + outputOffset] = ((intValue5 >>> 26) | (intValue6 << 6)) & mask;
+      output[7 + outputOffset] = ((intValue6 >>> 25) | (intValue7 << 7)) & mask;
+      output[8 + outputOffset] = ((intValue7 >>> 24) | (intValue8 << 8)) & mask;
+      output[9 + outputOffset] = ((intValue8 >>> 23) | (intValue9 << 9)) & mask;
+      output[10 + outputOffset] = ((intValue9 >>> 22) | (intValue10 << 10)) & mask;
+      output[11 + outputOffset] = ((intValue10 >>> 21) | (intValue11 << 11)) & mask;
+      output[12 + outputOffset] = ((intValue11 >>> 20) | (intValue12 << 12)) & mask;
+      output[13 + outputOffset] = ((intValue12 >>> 19) | (intValue13 << 13)) & mask;
+      output[14 + outputOffset] = ((intValue13 >>> 18) | (intValue14 << 14)) & mask;
+      output[15 + outputOffset] = ((intValue14 >>> 17) | (intValue15 << 15)) & mask;
+      output[16 + outputOffset] = ((intValue15 >>> 16) | (intValue16 << 16)) & mask;
+      output[17 + outputOffset] = ((intValue16 >>> 15) | (intValue17 << 17)) & mask;
+      output[18 + outputOffset] = ((intValue17 >>> 14) | (intValue18 << 18)) & mask;
+      output[19 + outputOffset] = ((intValue18 >>> 13) | (intValue19 << 19)) & mask;
+      output[20 + outputOffset] = ((intValue19 >>> 12) | (intValue20 << 20)) & mask;
+      output[21 + outputOffset] = ((intValue20 >>> 11) | (intValue21 << 21)) & mask;
+      output[22 + outputOffset] = ((intValue21 >>> 10) | (intValue22 << 22)) & mask;
+      output[23 + outputOffset] = ((intValue22 >>> 9) | (intValue23 << 23)) & mask;
+      output[24 + outputOffset] = ((intValue23 >>> 8) | (intValue24 << 24)) & mask;
+      output[25 + outputOffset] = ((intValue24 >>> 7) | (intValue25 << 25)) & mask;
+      output[26 + outputOffset] = ((intValue25 >>> 6) | (intValue26 << 26)) & mask;
+      output[27 + outputOffset] = ((intValue26 >>> 5) | (intValue27 << 27)) & mask;
+      output[28 + outputOffset] = ((intValue27 >>> 4) | (intValue28 << 28)) & mask;
+      output[29 + outputOffset] = ((intValue28 >>> 3) | (intValue29 << 29)) & mask;
+      output[30 + outputOffset] = ((intValue29 >>> 2) | (intValue30 << 30)) & mask;
+      output[31 + outputOffset] = intValue30 >>> 1;
+      outputOffset += 32;
+    }
+  }
+
+  // NOTE: hardwired to blockSize == 128
+  public static void decode32(final IntBuffer compressedBuffer, final int[] output) {
+    final int numFrameBits = 32;
+    final int mask = (int) ((1L<<numFrameBits) - 1);
+    int outputOffset = 0;
+    for(int step=0;step<4;step++) {
+      int intValue0 = compressedBuffer.get();
+      int intValue1 = compressedBuffer.get();
+      int intValue2 = compressedBuffer.get();
+      int intValue3 = compressedBuffer.get();
+      int intValue4 = compressedBuffer.get();
+      int intValue5 = compressedBuffer.get();
+      int intValue6 = compressedBuffer.get();
+      int intValue7 = compressedBuffer.get();
+      int intValue8 = compressedBuffer.get();
+      int intValue9 = compressedBuffer.get();
+      int intValue10 = compressedBuffer.get();
+      int intValue11 = compressedBuffer.get();
+      int intValue12 = compressedBuffer.get();
+      int intValue13 = compressedBuffer.get();
+      int intValue14 = compressedBuffer.get();
+      int intValue15 = compressedBuffer.get();
+      int intValue16 = compressedBuffer.get();
+      int intValue17 = compressedBuffer.get();
+      int intValue18 = compressedBuffer.get();
+      int intValue19 = compressedBuffer.get();
+      int intValue20 = compressedBuffer.get();
+      int intValue21 = compressedBuffer.get();
+      int intValue22 = compressedBuffer.get();
+      int intValue23 = compressedBuffer.get();
+      int intValue24 = compressedBuffer.get();
+      int intValue25 = compressedBuffer.get();
+      int intValue26 = compressedBuffer.get();
+      int intValue27 = compressedBuffer.get();
+      int intValue28 = compressedBuffer.get();
+      int intValue29 = compressedBuffer.get();
+      int intValue30 = compressedBuffer.get();
+      int intValue31 = compressedBuffer.get();
+      output[0 + outputOffset] = intValue0;
+      output[1 + outputOffset] = intValue1;
+      output[2 + outputOffset] = intValue2;
+      output[3 + outputOffset] = intValue3;
+      output[4 + outputOffset] = intValue4;
+      output[5 + outputOffset] = intValue5;
+      output[6 + outputOffset] = intValue6;
+      output[7 + outputOffset] = intValue7;
+      output[8 + outputOffset] = intValue8;
+      output[9 + outputOffset] = intValue9;
+      output[10 + outputOffset] = intValue10;
+      output[11 + outputOffset] = intValue11;
+      output[12 + outputOffset] = intValue12;
+      output[13 + outputOffset] = intValue13;
+      output[14 + outputOffset] = intValue14;
+      output[15 + outputOffset] = intValue15;
+      output[16 + outputOffset] = intValue16;
+      output[17 + outputOffset] = intValue17;
+      output[18 + outputOffset] = intValue18;
+      output[19 + outputOffset] = intValue19;
+      output[20 + outputOffset] = intValue20;
+      output[21 + outputOffset] = intValue21;
+      output[22 + outputOffset] = intValue22;
+      output[23 + outputOffset] = intValue23;
+      output[24 + outputOffset] = intValue24;
+      output[25 + outputOffset] = intValue25;
+      output[26 + outputOffset] = intValue26;
+      output[27 + outputOffset] = intValue27;
+      output[28 + outputOffset] = intValue28;
+      output[29 + outputOffset] = intValue29;
+      output[30 + outputOffset] = intValue30;
+      output[31 + outputOffset] = intValue31;
+      outputOffset += 32;
+    }
+  }
+}
Index: lucene/core/src/java/org/apache/lucene/codecs/pfor/PForFactory.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/pfor/PForFactory.java	(revision 0)
+++ lucene/core/src/java/org/apache/lucene/codecs/pfor/PForFactory.java	(working copy)
@@ -0,0 +1,159 @@
+package org.apache.lucene.codecs.pfor;
+/**
+ * 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.
+ */
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.IOContext;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.codecs.sep.IntStreamFactory;
+import org.apache.lucene.codecs.sep.IntIndexInput;
+import org.apache.lucene.codecs.sep.IntIndexOutput;
+import org.apache.lucene.codecs.intblock.FixedIntBlockIndexInput;
+import org.apache.lucene.codecs.intblock.FixedIntBlockIndexOutput;
+
+/** 
+ * Stuff to pass to PostingsReader/WriterBase.
+ * Things really make sense are: flushBlock() and readBlock()
+ */
+
+public class PForFactory extends IntStreamFactory {
+  private final int blockSize;
+
+  public PForFactory() {
+    this.blockSize=PForPostingsFormat.DEFAULT_BLOCK_SIZE;
+  }
+
+  @Override
+  public IntIndexOutput createOutput(Directory dir, String fileName, IOContext context)  throws IOException {
+    IndexOutput out = dir.createOutput(fileName, context);
+    boolean success = false;
+    try {
+      FixedIntBlockIndexOutput ret = new  PForIndexOutput(out, blockSize);
+      success = true;
+      return ret;
+    } finally {
+      if (!success) {
+        // TODO: why handle exception like this? 
+        // and why not use similar codes for read part?
+        IOUtils.closeWhileHandlingException(out);
+      }
+    }
+  }
+  @Override
+  public IntIndexInput openInput(Directory dir, String fileName, IOContext context) throws IOException {
+    FixedIntBlockIndexInput ret = new PForIndexInput(dir.openInput(fileName, context));
+    return ret;
+  }
+
+  // wrap input and output with buffer support
+  private class PForIndexInput extends FixedIntBlockIndexInput {
+    PForIndexInput(final IndexInput in) throws IOException {
+      super(in);
+    }
+    class PForBlockReader implements FixedIntBlockIndexInput.BlockReader {
+      byte[] encoded;
+      int[] buffer;
+      IndexInput in;
+      IntBuffer encodedBuffer;
+      PForBlockReader(final IndexInput in, final int[] buffer) {
+        this.encoded = new byte[blockSize*8+4];
+        this.in=in;
+        this.buffer=buffer;
+        this.encodedBuffer=ByteBuffer.wrap(encoded).asIntBuffer();
+      }
+      public void seek(long pos) {}
+      // TODO: implement public void skipBlock() {} ?
+      public void readBlock() throws IOException {
+        final int numBytes = in.readInt();
+        assert numBytes <= blockSize*8+4;
+        in.readBytes(encoded,0,numBytes);
+
+        encodedBuffer.rewind();
+        int header = encodedBuffer.get();
+
+        int numInts = (header & ((1<<8)-1)) + 1;
+        int excNum = ((header >> 8) & ((1<<8)-1)) + 1;
+        int excFirstPos = ((header >> 16) & ((1<<8)-1)) - 1;
+        int excBytes = PForUtil.PER_EXCEPTION_SIZE[(header >> 29) & ((1<<2)-1)];
+        int numBits = ((header >> 24) & ((1<<5)-1)) + 1;
+
+        // TODO: PForDecompressImpl is hardewired to size==128 only
+        switch(numBits) {
+          case 1: PForDecompressImpl.decode1(encodedBuffer, buffer); break;
+          case 2: PForDecompressImpl.decode2(encodedBuffer, buffer); break;
+          case 3: PForDecompressImpl.decode3(encodedBuffer, buffer); break;
+          case 4: PForDecompressImpl.decode4(encodedBuffer, buffer); break;
+          case 5: PForDecompressImpl.decode5(encodedBuffer, buffer); break;
+          case 6: PForDecompressImpl.decode6(encodedBuffer, buffer); break;
+          case 7: PForDecompressImpl.decode7(encodedBuffer, buffer); break;
+          case 8: PForDecompressImpl.decode8(encodedBuffer, buffer); break;
+          case 9: PForDecompressImpl.decode9(encodedBuffer, buffer); break;
+          case 10: PForDecompressImpl.decode10(encodedBuffer, buffer); break;
+          case 11: PForDecompressImpl.decode11(encodedBuffer, buffer); break;
+          case 12: PForDecompressImpl.decode12(encodedBuffer, buffer); break;
+          case 13: PForDecompressImpl.decode13(encodedBuffer, buffer); break;
+          case 14: PForDecompressImpl.decode14(encodedBuffer, buffer); break;
+          case 15: PForDecompressImpl.decode15(encodedBuffer, buffer); break;
+          case 16: PForDecompressImpl.decode16(encodedBuffer, buffer); break;
+          case 17: PForDecompressImpl.decode17(encodedBuffer, buffer); break;
+          case 18: PForDecompressImpl.decode18(encodedBuffer, buffer); break;
+          case 19: PForDecompressImpl.decode19(encodedBuffer, buffer); break;
+          case 20: PForDecompressImpl.decode20(encodedBuffer, buffer); break;
+          case 21: PForDecompressImpl.decode21(encodedBuffer, buffer); break;
+          case 22: PForDecompressImpl.decode22(encodedBuffer, buffer); break;
+          case 23: PForDecompressImpl.decode23(encodedBuffer, buffer); break;
+          case 24: PForDecompressImpl.decode24(encodedBuffer, buffer); break;
+          case 25: PForDecompressImpl.decode25(encodedBuffer, buffer); break;
+          case 26: PForDecompressImpl.decode26(encodedBuffer, buffer); break;
+          case 27: PForDecompressImpl.decode27(encodedBuffer, buffer); break;
+          case 28: PForDecompressImpl.decode28(encodedBuffer, buffer); break;
+          case 29: PForDecompressImpl.decode29(encodedBuffer, buffer); break;
+          case 30: PForDecompressImpl.decode30(encodedBuffer, buffer); break;
+          case 31: PForDecompressImpl.decode31(encodedBuffer, buffer); break;
+          case 32: PForDecompressImpl.decode32(encodedBuffer, buffer); break;
+        }
+        PForUtil.patchException(encodedBuffer,buffer,excNum,excFirstPos,excBytes);
+      }
+    }
+    @Override
+    protected BlockReader getBlockReader(final IndexInput in, final int[] buffer) throws IOException {
+      return new PForBlockReader(in,buffer);
+    }
+  }
+
+  private class PForIndexOutput extends FixedIntBlockIndexOutput {
+      private byte[] encoded;
+      private IntBuffer encodedBuffer;
+    PForIndexOutput(IndexOutput out, int blockSize) throws IOException {
+      super(out,blockSize);
+      this.encoded = new byte[blockSize*8+4];
+      this.encodedBuffer=ByteBuffer.wrap(encoded).asIntBuffer();
+    }
+    @Override
+    protected void flushBlock() throws IOException {
+      final int numBytes = PForUtil.compress(buffer,buffer.length,encodedBuffer);
+      out.writeInt(numBytes);
+      out.writeBytes(encoded, numBytes);
+    }
+  }
+}
