From 46cedfe530e56d08c54d85a7dd9c6c143c41dee9 Mon Sep 17 00:00:00 2001 From: Vojtech Moravec <vojtech.moravec.st@vsb.cz> Date: Mon, 14 Sep 2020 10:29:36 +0200 Subject: [PATCH] Add preloadGlobalCodebook method. This method is used for stream compressor/decompressor. It will cache the codebook and huffman tree so that each compression/decompression pass don't have to create it. --- .../compression/IImageDecompressor.java | 8 +++++ .../compression/SQImageDecompressor.java | 30 ++++++++++++++++--- .../compression/VQImageDecompressor.java | 15 ++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/main/java/azgracompress/compression/IImageDecompressor.java b/src/main/java/azgracompress/compression/IImageDecompressor.java index 7e2d35c..340d9b9 100644 --- a/src/main/java/azgracompress/compression/IImageDecompressor.java +++ b/src/main/java/azgracompress/compression/IImageDecompressor.java @@ -1,5 +1,6 @@ package azgracompress.compression; +import azgracompress.cache.ICacheFile; import azgracompress.compression.exception.ImageDecompressionException; import azgracompress.fileformat.QCMPFileHeader; @@ -38,4 +39,11 @@ public interface IImageDecompressor extends IListenable { void decompressToBuffer(DataInputStream compressedStream, short[][] buffer, final QCMPFileHeader header) throws ImageDecompressionException; + + /** + * Preload decompressor codebook and Huffman tree for stream decompressor from provided cache file. + * + * @param codebookCacheFile Codebook cache file. + */ + void preloadGlobalCodebook(final ICacheFile codebookCacheFile); } diff --git a/src/main/java/azgracompress/compression/SQImageDecompressor.java b/src/main/java/azgracompress/compression/SQImageDecompressor.java index 5be07a8..0fda46e 100644 --- a/src/main/java/azgracompress/compression/SQImageDecompressor.java +++ b/src/main/java/azgracompress/compression/SQImageDecompressor.java @@ -1,5 +1,8 @@ package azgracompress.compression; +import azgracompress.cache.ICacheFile; +import azgracompress.cache.SQCacheFile; +import azgracompress.cache.VQCacheFile; import azgracompress.compression.exception.ImageDecompressionException; import azgracompress.fileformat.QCMPFileHeader; import azgracompress.huffman.Huffman; @@ -14,6 +17,9 @@ import java.io.DataOutputStream; import java.io.IOException; public class SQImageDecompressor extends CompressorDecompressorBase implements IImageDecompressor { + private SQCodebook cachedCodebook = null; + private Huffman cachedHuffman = null; + public SQImageDecompressor(CompressionOptions options) { super(options); } @@ -88,8 +94,8 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I byte[] decompressedPlaneData = null; final int planeDataSize = (int) header.getPlaneDataSizes()[planeIndex]; try (InBitStream inBitStream = new InBitStream(compressedStream, - header.getBitsPerCodebookIndex(), - planeDataSize)) { + header.getBitsPerCodebookIndex(), + planeDataSize)) { inBitStream.readToBuffer(); inBitStream.setAllowReadFromUnderlyingStream(false); @@ -124,7 +130,19 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I } @Override - public void decompressToBuffer(DataInputStream compressedStream, short[][] buffer, QCMPFileHeader header) throws ImageDecompressionException { + public void preloadGlobalCodebook(final ICacheFile codebookCacheFile) { + assert (codebookCacheFile instanceof SQCacheFile) : "Incorrect codebook cache file type for SQImageDecompressor"; + + SQCacheFile codebookCache = (SQCacheFile) codebookCacheFile; + + cachedCodebook = codebookCache.getCodebook(); + cachedHuffman = createHuffmanCoder(createHuffmanSymbols(cachedCodebook.getCodebookSize()), cachedCodebook.getSymbolFrequencies()); + } + + @Override + public void decompressToBuffer(DataInputStream compressedStream, + short[][] buffer, + QCMPFileHeader header) throws ImageDecompressionException { final int codebookSize = (int) Math.pow(2, header.getBitsPerCodebookIndex()); final int[] huffmanSymbols = createHuffmanSymbols(codebookSize); final int planeCountForDecompression = header.getImageSizeZ(); @@ -166,8 +184,12 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I buffer[planeIndex] = TypeConverter.intArrayToShortArray(decompressedValues); } catch (Exception ex) { - throw new ImageDecompressionException("SQImageDecompressor::decompressToBuffer() - Unable to read indices from InBitStream.", ex); + throw new ImageDecompressionException("SQImageDecompressor::decompressToBuffer() - Unable to read indices from " + + "InBitStream.", + ex); } } + + } } diff --git a/src/main/java/azgracompress/compression/VQImageDecompressor.java b/src/main/java/azgracompress/compression/VQImageDecompressor.java index 383dea0..12b6bb8 100644 --- a/src/main/java/azgracompress/compression/VQImageDecompressor.java +++ b/src/main/java/azgracompress/compression/VQImageDecompressor.java @@ -1,5 +1,8 @@ package azgracompress.compression; +import azgracompress.cache.ICacheFile; +import azgracompress.cache.SQCacheFile; +import azgracompress.cache.VQCacheFile; import azgracompress.compression.exception.ImageDecompressionException; import azgracompress.data.*; import azgracompress.fileformat.QCMPFileHeader; @@ -17,6 +20,9 @@ import java.io.IOException; public class VQImageDecompressor extends CompressorDecompressorBase implements IImageDecompressor { + private VQCodebook cachedCodebook = null; + private Huffman cachedHuffman = null; + private interface DecompressCallback { void process(final Block imageBlock, final int planeIndex) throws ImageDecompressionException; } @@ -67,6 +73,15 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I return new VQCodebook(new V3i(0), codebookVectors, frequencies); } + @Override + public void preloadGlobalCodebook(final ICacheFile codebookCacheFile) { + assert (codebookCacheFile instanceof VQCacheFile) : "Incorrect codebook cache file type for VQImageDecompressor"; + VQCacheFile codebookCache = (VQCacheFile) codebookCacheFile; + + cachedCodebook = codebookCache.getCodebook(); + cachedHuffman = createHuffmanCoder(createHuffmanSymbols(cachedCodebook.getCodebookSize()), cachedCodebook.getVectorFrequencies()); + } + private Block reconstructImageFromQuantizedVectors(final int[][] vectors, final V2i qVector, -- GitLab