diff --git a/src/main/java/me/lemire/integercompression/SkippableComposition.java b/src/main/java/me/lemire/integercompression/SkippableComposition.java index 7dd4736..fc3c18e 100644 --- a/src/main/java/me/lemire/integercompression/SkippableComposition.java +++ b/src/main/java/me/lemire/integercompression/SkippableComposition.java @@ -52,12 +52,14 @@ public void headlessCompress(int[] in, IntWrapper inpos, int inlength, int[] out public void headlessUncompress(int[] in, IntWrapper inpos, int inlength, int[] out, IntWrapper outpos, int num) { int init = inpos.get(); + int outposInit = outpos.get(); + F1.headlessUncompress(in, inpos, inlength, out, outpos, num); if (inpos.get() == init) { inpos.increment(); } inlength -= inpos.get() - init; - num -= outpos.get(); + num -= outpos.get() - outposInit; F2.headlessUncompress(in, inpos, inlength, out, outpos, num); } diff --git a/src/main/java/me/lemire/integercompression/differential/SkippableIntegratedComposition.java b/src/main/java/me/lemire/integercompression/differential/SkippableIntegratedComposition.java index a1379ad..4786ec5 100644 --- a/src/main/java/me/lemire/integercompression/differential/SkippableIntegratedComposition.java +++ b/src/main/java/me/lemire/integercompression/differential/SkippableIntegratedComposition.java @@ -66,13 +66,15 @@ public void headlessUncompress(int[] in, IntWrapper inpos, int inlength, if (inlength == 0) return; int init = inpos.get(); + int outposInit = outpos.get(); + F1.headlessUncompress(in, inpos, inlength, out, outpos,num,initvalue); if (inpos.get() == init) { inpos.increment(); } inlength -= inpos.get() - init; - num -= outpos.get(); + num -= outpos.get() - outposInit; F2.headlessUncompress(in, inpos, inlength, out, outpos,num,initvalue); } diff --git a/src/main/java/me/lemire/longcompression/SkippableLongComposition.java b/src/main/java/me/lemire/longcompression/SkippableLongComposition.java index 0f9800e..eb03b72 100644 --- a/src/main/java/me/lemire/longcompression/SkippableLongComposition.java +++ b/src/main/java/me/lemire/longcompression/SkippableLongComposition.java @@ -53,12 +53,14 @@ public void headlessCompress(long[] in, IntWrapper inpos, int inlength, long[] o public void headlessUncompress(long[] in, IntWrapper inpos, int inlength, long[] out, IntWrapper outpos, int num) { int init = inpos.get(); + int outposInit = outpos.get(); + F1.headlessUncompress(in, inpos, inlength, out, outpos, num); if (inpos.get() == init) { inpos.increment(); } inlength -= inpos.get() - init; - num -= outpos.get(); + num -= outpos.get() - outposInit; F2.headlessUncompress(in, inpos, inlength, out, outpos, num); } diff --git a/src/test/java/me/lemire/integercompression/SkippableBasicTest.java b/src/test/java/me/lemire/integercompression/SkippableBasicTest.java index 57a07e3..881dada 100644 --- a/src/test/java/me/lemire/integercompression/SkippableBasicTest.java +++ b/src/test/java/me/lemire/integercompression/SkippableBasicTest.java @@ -15,6 +15,7 @@ import me.lemire.integercompression.differential.SkippableIntegratedIntegerCODEC; import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; /** @@ -236,4 +237,52 @@ private static void testMaxHeadlessCompressedLength(SkippableIntegerCODEC codec, } } } + + @Test + public void testUncompressOutputOffset_SkippableComposition() { + for (int offset : new int[] {0, 1, 6}) { + SkippableComposition codec = new SkippableComposition(new BinaryPacking(), new VariableByte()); + + int[] input = { 2, 3, 4, 5 }; + int[] compressed = new int[codec.maxHeadlessCompressedLength(new IntWrapper(0), input.length)]; + int[] uncompressed = new int[offset + input.length]; + + IntWrapper inputOffset = new IntWrapper(0); + IntWrapper compressedOffset = new IntWrapper(0); + + codec.headlessCompress(input, inputOffset, input.length, compressed, compressedOffset); + + int compressedLength = compressedOffset.get(); + IntWrapper uncompressedOffset = new IntWrapper(offset); + compressedOffset = new IntWrapper(0); + codec.headlessUncompress(compressed, compressedOffset, compressedLength, uncompressed, uncompressedOffset, input.length); + + assertArrayEquals(input, Arrays.copyOfRange(uncompressed, offset, offset + input.length)); + } + } + + @Test + public void testUncompressOutputOffset_SkippableIntegratedComposition() { + for (int offset : new int[] {0, 1, 6}) { + SkippableIntegratedComposition codec = new SkippableIntegratedComposition(new IntegratedBinaryPacking(), new IntegratedVariableByte()); + + int[] input = { 2, 3, 4, 5 }; + int[] compressed = new int[codec.maxHeadlessCompressedLength(new IntWrapper(0), input.length)]; + int[] uncompressed = new int[offset + input.length]; + + IntWrapper inputOffset = new IntWrapper(0); + IntWrapper compressedOffset = new IntWrapper(0); + IntWrapper initValue = new IntWrapper(0); + + codec.headlessCompress(input, inputOffset, input.length, compressed, compressedOffset, initValue); + + int compressedLength = compressedOffset.get(); + IntWrapper uncompressedOffset = new IntWrapper(offset); + compressedOffset = new IntWrapper(0); + initValue = new IntWrapper(0); + codec.headlessUncompress(compressed, compressedOffset, compressedLength, uncompressed, uncompressedOffset, input.length, initValue); + + assertArrayEquals(input, Arrays.copyOfRange(uncompressed, offset, offset + input.length)); + } + } } diff --git a/src/test/java/me/lemire/longcompression/SkippableLongBasicTest.java b/src/test/java/me/lemire/longcompression/SkippableLongBasicTest.java index 4309e9d..c4b7e01 100644 --- a/src/test/java/me/lemire/longcompression/SkippableLongBasicTest.java +++ b/src/test/java/me/lemire/longcompression/SkippableLongBasicTest.java @@ -15,6 +15,7 @@ import me.lemire.integercompression.TestUtils; import me.lemire.integercompression.VariableByte; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; /** @@ -167,4 +168,27 @@ private static void testMaxHeadlessCompressedLength(SkippableLongCODEC codec, in assertTrue(maxOutputLength <= outPos.get() + 1); // +1 because SkippableLongComposition always adds one extra integer for the potential header } } + + @Test + public void testUncompressOutputOffset_SkippableLongComposition() { + for (int offset : new int[] {0, 1, 6}) { + SkippableLongComposition codec = new SkippableLongComposition(new LongBinaryPacking(), new LongVariableByte()); + + long[] input = { 2, 3, 4, 5 }; + long[] compressed = new long[codec.maxHeadlessCompressedLength(new IntWrapper(0), input.length)]; + long[] uncompressed = new long[offset + input.length]; + + IntWrapper inputOffset = new IntWrapper(0); + IntWrapper compressedOffset = new IntWrapper(0); + + codec.headlessCompress(input, inputOffset, input.length, compressed, compressedOffset); + + int compressedLength = compressedOffset.get(); + IntWrapper uncompressedOffset = new IntWrapper(offset); + compressedOffset = new IntWrapper(0); + codec.headlessUncompress(compressed, compressedOffset, compressedLength, uncompressed, uncompressedOffset, input.length); + + assertArrayEquals(input, Arrays.copyOfRange(uncompressed, offset, offset + input.length)); + } + } }