From f55cdca68160fdf5c5253b92c561a0a68c9f716c Mon Sep 17 00:00:00 2001 From: Vojtech Moravec <vojtech.moravec.st@vsb.cz> Date: Wed, 2 Dec 2020 14:27:03 +0100 Subject: [PATCH] Write binary encoded huffman tree in compression. This can't be used fully atm, becuase we haven't updated the QCMP file header to report ver.2. The Decompressors will now try to read frequencies values, which will fail! --- .../java/cz/it4i/qcmp/compression/ImageCompressor.java | 1 + .../java/cz/it4i/qcmp/compression/SQImageCompressor.java | 8 +++++--- .../cz/it4i/qcmp/compression/SQImageDecompressor.java | 1 + .../java/cz/it4i/qcmp/compression/VQImageCompressor.java | 7 +++---- .../cz/it4i/qcmp/compression/VQImageDecompressor.java | 1 + 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/cz/it4i/qcmp/compression/ImageCompressor.java b/src/main/java/cz/it4i/qcmp/compression/ImageCompressor.java index 3ff365c..7ff58e1 100644 --- a/src/main/java/cz/it4i/qcmp/compression/ImageCompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/ImageCompressor.java @@ -217,6 +217,7 @@ public class ImageCompressor extends CompressorDecompressorBase { * @return Valid QCMPFile header for compressed file. */ private QCMPFileHeader createHeader() { + // TODO(Moravec): Change header to newer version! final QCMPFileHeader header = new QCMPFileHeader(); diff --git a/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java b/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java index aee6464..2a5e8f0 100644 --- a/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java @@ -7,6 +7,7 @@ import cz.it4i.qcmp.cache.SqQvcFile; import cz.it4i.qcmp.compression.exception.ImageCompressionException; import cz.it4i.qcmp.huffman.HuffmanEncoder; import cz.it4i.qcmp.io.InputData; +import cz.it4i.qcmp.io.OutBitStream; import cz.it4i.qcmp.io.loader.IPlaneLoader; import cz.it4i.qcmp.io.loader.PlaneLoaderFactory; import cz.it4i.qcmp.quantization.scalar.LloydMaxU16ScalarQuantization; @@ -59,14 +60,15 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm final DataOutputStream compressStream) throws ImageCompressionException { final SQCodebook codebook = quantizer.getCodebook(); final int[] centroids = codebook.getCentroids(); - final long[] frequencies = codebook.getSymbolFrequencies(); try { for (final int quantizationValue : centroids) { compressStream.writeShort(quantizationValue); } - for (final long symbolFrequency : frequencies) { - compressStream.writeLong(symbolFrequency); + + try (final OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerCodebookIndex(), 32)) { + codebook.getHuffmanTreeRoot().writeToBinaryStream(outBitStream); } + } catch (final IOException ioEx) { throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx); } diff --git a/src/main/java/cz/it4i/qcmp/compression/SQImageDecompressor.java b/src/main/java/cz/it4i/qcmp/compression/SQImageDecompressor.java index e3433a4..a7c3c42 100644 --- a/src/main/java/cz/it4i/qcmp/compression/SQImageDecompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/SQImageDecompressor.java @@ -30,6 +30,7 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I for (int i = 0; i < codebookSize; i++) { quantizationValues[i] = compressedStream.readUnsignedShort(); } + // TODO(Moravec): Read frequencies or binary huffman tree based on file format version!!! for (int i = 0; i < codebookSize; i++) { symbolFrequencies[i] = compressedStream.readLong(); } diff --git a/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java b/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java index 0bdd52f..0c8c112 100644 --- a/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java @@ -8,6 +8,7 @@ import cz.it4i.qcmp.data.Range; import cz.it4i.qcmp.fileformat.QuantizationType; import cz.it4i.qcmp.huffman.HuffmanEncoder; import cz.it4i.qcmp.io.InputData; +import cz.it4i.qcmp.io.OutBitStream; import cz.it4i.qcmp.io.loader.IPlaneLoader; import cz.it4i.qcmp.io.loader.PlaneLoaderFactory; import cz.it4i.qcmp.quantization.vector.LBGResult; @@ -72,7 +73,6 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm */ private void writeQuantizerToCompressStream(final VectorQuantizer quantizer, final DataOutputStream compressStream) throws ImageCompressionException { - // TODO final int[][] codebook = quantizer.getCodebookVectors(); try { for (final int[] entry : codebook) { @@ -80,9 +80,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm compressStream.writeShort(vecVal); } } - final long[] frequencies = quantizer.getFrequencies(); - for (final long symbolFrequency : frequencies) { - compressStream.writeLong(symbolFrequency); + try (final OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerCodebookIndex(), 32)) { + quantizer.getCodebook().getHuffmanTreeRoot().writeToBinaryStream(outBitStream); } } catch (final IOException ioEx) { throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx); diff --git a/src/main/java/cz/it4i/qcmp/compression/VQImageDecompressor.java b/src/main/java/cz/it4i/qcmp/compression/VQImageDecompressor.java index 65af70f..87bc9c7 100644 --- a/src/main/java/cz/it4i/qcmp/compression/VQImageDecompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/VQImageDecompressor.java @@ -56,6 +56,7 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I codebookVectors[codebookIndex][vecIndex] = compressedStream.readUnsignedShort(); } } + // TODO(Moravec): Read frequencies or binary huffman tree based on file format version!!! for (int codebookIndex = 0; codebookIndex < codebookSize; codebookIndex++) { frequencies[codebookIndex] = compressedStream.readLong(); } -- GitLab