Skip to content

Commit

Permalink
Allow unzipping using an offset into the uncompressed and compressed …
Browse files Browse the repository at this point in the history
…arrays. (#651)
  • Loading branch information
nh13 authored and tfenne committed Jun 25, 2016
1 parent ec44a54 commit 4cd5ef9
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions src/main/java/htsjdk/samtools/util/BlockGunzipper.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,26 @@ public void setCheckCrcs(final boolean check) {
* @param uncompressedBlock must be big enough to hold decompressed output.
* @param compressedBlock compressed data starting at offset 0
* @param compressedLength size of compressed data, possibly less than the size of the buffer.
* @return the uncompressed data size.
*/
public void unzipBlock(byte[] uncompressedBlock, byte[] compressedBlock, int compressedLength) {
public int unzipBlock(byte[] uncompressedBlock, byte[] compressedBlock, int compressedLength) {
return unzipBlock(uncompressedBlock, 0, compressedBlock, 0, compressedLength);
}

/**
* Decompress GZIP-compressed data
* @param uncompressedBlock must be big enough to hold decompressed output.
* @param uncompressedBlockOffset the offset into uncompressedBlock.
* @param compressedBlock compressed data starting at offset 0.
* @param compressedBlock the offset into the compressed data.
* @param compressedLength size of compressed data, possibly less than the size of the buffer.
* @return the uncompressed data size.
*/
public int unzipBlock(byte[] uncompressedBlock, int uncompressedBlockOffset,
byte[] compressedBlock, int compressedBlockOffset, int compressedLength) {
int uncompressedSize;
try {
ByteBuffer byteBuffer = ByteBuffer.wrap(compressedBlock, 0, compressedLength);
ByteBuffer byteBuffer = ByteBuffer.wrap(compressedBlock, compressedBlockOffset, compressedLength);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);

// Validate GZIP header
Expand Down Expand Up @@ -88,20 +104,20 @@ public void unzipBlock(byte[] uncompressedBlock, byte[] compressedBlock, int com
final int deflatedSize = compressedLength - BlockCompressedStreamConstants.BLOCK_HEADER_LENGTH - BlockCompressedStreamConstants.BLOCK_FOOTER_LENGTH;
byteBuffer.position(byteBuffer.position() + deflatedSize);
int expectedCrc = byteBuffer.getInt();
int uncompressedSize = byteBuffer.getInt();
uncompressedSize = byteBuffer.getInt();
inflater.reset();

// Decompress
inflater.setInput(compressedBlock, BlockCompressedStreamConstants.BLOCK_HEADER_LENGTH, deflatedSize);
final int inflatedBytes = inflater.inflate(uncompressedBlock, 0, uncompressedSize);
inflater.setInput(compressedBlock, compressedBlockOffset + BlockCompressedStreamConstants.BLOCK_HEADER_LENGTH, deflatedSize);
final int inflatedBytes = inflater.inflate(uncompressedBlock, uncompressedBlockOffset, uncompressedSize);
if (inflatedBytes != uncompressedSize) {
throw new SAMFormatException("Did not inflate expected amount");
}

// Validate CRC if so desired
if (this.checkCrcs) {
crc32.reset();
crc32.update(uncompressedBlock, 0, uncompressedSize);
crc32.update(uncompressedBlock, uncompressedBlockOffset, uncompressedSize);
final long crc = crc32.getValue();
if ((int)crc != expectedCrc) {
throw new SAMFormatException("CRC mismatch");
Expand All @@ -111,5 +127,6 @@ public void unzipBlock(byte[] uncompressedBlock, byte[] compressedBlock, int com
{
throw new RuntimeIOException(e);
}
return uncompressedSize;
}
}

0 comments on commit 4cd5ef9

Please sign in to comment.