public void headlessCompress(int[] @in, IntWrapper inpos, int inlength, int[] @out, IntWrapper outpos, IntWrapper initvalue)
        {
            inlength = Util.greatestMultiple(inlength, BLOCK_SIZE);
            if (inlength == 0)
            {
                return;
            }
            int tmpoutpos  = outpos.get();
            int initoffset = initvalue.get();

            initvalue.set(@in[inpos.get() + inlength - 1]);
            int s = inpos.get();

            for (; s + BLOCK_SIZE * 4 - 1 < inpos.get() + inlength; s += BLOCK_SIZE * 4)
            {
                int mbits1      = Util.maxdiffbits(initoffset, @in, s, BLOCK_SIZE);
                int initoffset2 = @in[s + 31];
                int mbits2      = Util.maxdiffbits(initoffset2, @in, s + BLOCK_SIZE, BLOCK_SIZE);
                int initoffset3 = @in[s + BLOCK_SIZE + 31];
                int mbits3      = Util
                                  .maxdiffbits(initoffset3, @in, s + 2 * BLOCK_SIZE, BLOCK_SIZE);
                int initoffset4 = @in[s + 2 * BLOCK_SIZE + 31];
                int mbits4      = Util
                                  .maxdiffbits(initoffset4, @in, s + 3 * BLOCK_SIZE, BLOCK_SIZE);
                @out[tmpoutpos++] = (mbits1 << 24) | (mbits2 << 16) | (mbits3 << 8)
                                    | (mbits4);
                IntegratedBitPacking.integratedpack(initoffset, @in, s, @out,
                                                    tmpoutpos, mbits1);
                tmpoutpos += mbits1;
                IntegratedBitPacking.integratedpack(initoffset2, @in, s + BLOCK_SIZE, @out,
                                                    tmpoutpos, mbits2);
                tmpoutpos += mbits2;
                IntegratedBitPacking.integratedpack(initoffset3, @in, s + 2 * BLOCK_SIZE,
                                                    @out, tmpoutpos, mbits3);
                tmpoutpos += mbits3;
                IntegratedBitPacking.integratedpack(initoffset4, @in, s + 3 * BLOCK_SIZE,
                                                    @out, tmpoutpos, mbits4);
                tmpoutpos += mbits4;
                initoffset = @in[s + 3 * BLOCK_SIZE + 31];
            }
            for (; s < inpos.get() + inlength; s += BLOCK_SIZE)
            {
                int mbits = Util.maxdiffbits(initoffset, @in, s, BLOCK_SIZE);
                @out[tmpoutpos++] = mbits;
                IntegratedBitPacking.integratedpack(initoffset, @in, s, @out,
                                                    tmpoutpos, mbits);
                tmpoutpos += mbits;
                initoffset = @in[s + 31];
            }
            inpos.add(inlength);
            outpos.set(tmpoutpos);
        }
        public void headlessUncompress(int[] @in, IntWrapper inpos, int inlength, int[] @out, IntWrapper outpos, int num, IntWrapper initvalue)
        {
            int outlength  = Util.greatestMultiple(num, BLOCK_SIZE);
            int tmpinpos   = inpos.get();
            int initoffset = initvalue.get();
            int s          = outpos.get();

            for (; s + BLOCK_SIZE * 4 - 1 < outpos.get() + outlength; s += BLOCK_SIZE * 4)
            {
                int mbits1 = (int)((uint)@in[tmpinpos] >> 24);
                int mbits2 = (int)((uint)@in[tmpinpos] >> 16) & 0xFF;
                int mbits3 = (int)((uint)@in[tmpinpos] >> 8) & 0xFF;
                int mbits4 = (@in[tmpinpos]) & 0xFF;

                ++tmpinpos;
                IntegratedBitPacking.integratedunpack(initoffset, @in, tmpinpos,
                                                      @out, s, mbits1);
                tmpinpos  += mbits1;
                initoffset = @out[s + 31];
                IntegratedBitPacking.integratedunpack(initoffset, @in, tmpinpos,
                                                      @out, s + BLOCK_SIZE, mbits2);
                tmpinpos  += mbits2;
                initoffset = @out[s + BLOCK_SIZE + 31];
                IntegratedBitPacking.integratedunpack(initoffset, @in, tmpinpos,
                                                      @out, s + 2 * BLOCK_SIZE, mbits3);
                tmpinpos  += mbits3;
                initoffset = @out[s + 2 * BLOCK_SIZE + 31];
                IntegratedBitPacking.integratedunpack(initoffset, @in, tmpinpos,
                                                      @out, s + 3 * BLOCK_SIZE, mbits4);
                tmpinpos  += mbits4;
                initoffset = @out[s + 3 * BLOCK_SIZE + 31];
            }
            for (; s < outpos.get() + outlength; s += BLOCK_SIZE)
            {
                int mbits = @in[tmpinpos];
                ++tmpinpos;
                IntegratedBitPacking.integratedunpack(initoffset, @in, tmpinpos,
                                                      @out, s, mbits);
                initoffset = @out[s + 31];

                tmpinpos += mbits;
            }
            outpos.add(outlength);
            initvalue.set(initoffset);
            inpos.set(tmpinpos);
        }
        public static void testWithDeltas(bool verbose)
        {
            const int N     = 32;
            const int times = 100000;

            Random r = new Random(0);

            int[] data         = new int[N];
            int[] compressed   = new int[N];
            int[] icompressed  = new int[N];
            int[] uncompressed = new int[N];

            for (int bit = 1; bit < 31; ++bit)
            {
                long comp    = 0;
                long decomp  = 0;
                long icomp   = 0;
                long idecomp = 0;

                for (int t = 0; t < times; ++t)
                {
                    data[0] = r.Next(1 << bit);
                    for (int k = 1; k < N; ++k)
                    {
                        data[k] = r.Next(1 << bit)
                                  + data[k - 1];
                    }

                    int[] tmpdata = Arrays.copyOf(data, data.Length);

                    long time1 = Port.System.nanoTime();
                    Delta.delta(tmpdata);
                    BitPacking.fastpackwithoutmask(tmpdata, 0,
                                                   compressed, 0, bit);
                    long time2 = Port.System.nanoTime();
                    BitPacking.fastunpack(compressed, 0,
                                          uncompressed, 0, bit);
                    Delta.fastinverseDelta(uncompressed);
                    long time3 = Port.System.nanoTime();
                    if (!Arrays.equals(data, uncompressed))
                    {
                        throw new Exception("bug");
                    }
                    comp   += time2 - time1;
                    decomp += time3 - time2;
                    tmpdata = Arrays.copyOf(data, data.Length);
                    time1   = Port.System.nanoTime();
                    IntegratedBitPacking.integratedpack(0, tmpdata,
                                                        0, icompressed, 0, bit);
                    time2 = Port.System.nanoTime();
                    IntegratedBitPacking.integratedunpack(0,
                                                          icompressed, 0, uncompressed, 0, bit);
                    time3 = Port.System.nanoTime();
                    if (!Arrays.equals(icompressed, compressed))
                    {
                        throw new Exception("ibug " + bit);
                    }

                    if (!Arrays.equals(data, uncompressed))
                    {
                        throw new Exception("bug " + bit);
                    }
                    icomp   += time2 - time1;
                    idecomp += time3 - time2;
                }

                if (verbose)
                {
                    Console.WriteLine("bit = "
                                      + bit
                                      + " comp. speed = "
                                      + (N * times * 1000.0 / (comp)).ToString("0")
                                      + " decomp. speed = "
                                      + (N * times * 1000.0 / (decomp)).ToString("0")
                                      + " icomp. speed = "
                                      + (N * times * 1000.0 / (icomp)).ToString("0")
                                      + " idecomp. speed = "
                                      + (N * times * 1000.0 / (idecomp)).ToString("0"));
                }
            }
        }