Skip to content
Snippets Groups Projects
Commit f55cdca6 authored by Vojtech Moravec's avatar Vojtech Moravec
Browse files

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!
parent 85704457
No related branches found
No related tags found
No related merge requests found
...@@ -217,6 +217,7 @@ public class ImageCompressor extends CompressorDecompressorBase { ...@@ -217,6 +217,7 @@ public class ImageCompressor extends CompressorDecompressorBase {
* @return Valid QCMPFile header for compressed file. * @return Valid QCMPFile header for compressed file.
*/ */
private QCMPFileHeader createHeader() { private QCMPFileHeader createHeader() {
// TODO(Moravec): Change header to newer version!
final QCMPFileHeader header = new QCMPFileHeader(); final QCMPFileHeader header = new QCMPFileHeader();
......
...@@ -7,6 +7,7 @@ import cz.it4i.qcmp.cache.SqQvcFile; ...@@ -7,6 +7,7 @@ import cz.it4i.qcmp.cache.SqQvcFile;
import cz.it4i.qcmp.compression.exception.ImageCompressionException; import cz.it4i.qcmp.compression.exception.ImageCompressionException;
import cz.it4i.qcmp.huffman.HuffmanEncoder; import cz.it4i.qcmp.huffman.HuffmanEncoder;
import cz.it4i.qcmp.io.InputData; 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.IPlaneLoader;
import cz.it4i.qcmp.io.loader.PlaneLoaderFactory; import cz.it4i.qcmp.io.loader.PlaneLoaderFactory;
import cz.it4i.qcmp.quantization.scalar.LloydMaxU16ScalarQuantization; import cz.it4i.qcmp.quantization.scalar.LloydMaxU16ScalarQuantization;
...@@ -59,14 +60,15 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm ...@@ -59,14 +60,15 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
final DataOutputStream compressStream) throws ImageCompressionException { final DataOutputStream compressStream) throws ImageCompressionException {
final SQCodebook codebook = quantizer.getCodebook(); final SQCodebook codebook = quantizer.getCodebook();
final int[] centroids = codebook.getCentroids(); final int[] centroids = codebook.getCentroids();
final long[] frequencies = codebook.getSymbolFrequencies();
try { try {
for (final int quantizationValue : centroids) { for (final int quantizationValue : centroids) {
compressStream.writeShort(quantizationValue); 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) { } catch (final IOException ioEx) {
throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx); throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx);
} }
......
...@@ -30,6 +30,7 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I ...@@ -30,6 +30,7 @@ public class SQImageDecompressor extends CompressorDecompressorBase implements I
for (int i = 0; i < codebookSize; i++) { for (int i = 0; i < codebookSize; i++) {
quantizationValues[i] = compressedStream.readUnsignedShort(); quantizationValues[i] = compressedStream.readUnsignedShort();
} }
// TODO(Moravec): Read frequencies or binary huffman tree based on file format version!!!
for (int i = 0; i < codebookSize; i++) { for (int i = 0; i < codebookSize; i++) {
symbolFrequencies[i] = compressedStream.readLong(); symbolFrequencies[i] = compressedStream.readLong();
} }
......
...@@ -8,6 +8,7 @@ import cz.it4i.qcmp.data.Range; ...@@ -8,6 +8,7 @@ import cz.it4i.qcmp.data.Range;
import cz.it4i.qcmp.fileformat.QuantizationType; import cz.it4i.qcmp.fileformat.QuantizationType;
import cz.it4i.qcmp.huffman.HuffmanEncoder; import cz.it4i.qcmp.huffman.HuffmanEncoder;
import cz.it4i.qcmp.io.InputData; 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.IPlaneLoader;
import cz.it4i.qcmp.io.loader.PlaneLoaderFactory; import cz.it4i.qcmp.io.loader.PlaneLoaderFactory;
import cz.it4i.qcmp.quantization.vector.LBGResult; import cz.it4i.qcmp.quantization.vector.LBGResult;
...@@ -72,7 +73,6 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm ...@@ -72,7 +73,6 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
*/ */
private void writeQuantizerToCompressStream(final VectorQuantizer quantizer, private void writeQuantizerToCompressStream(final VectorQuantizer quantizer,
final DataOutputStream compressStream) throws ImageCompressionException { final DataOutputStream compressStream) throws ImageCompressionException {
// TODO
final int[][] codebook = quantizer.getCodebookVectors(); final int[][] codebook = quantizer.getCodebookVectors();
try { try {
for (final int[] entry : codebook) { for (final int[] entry : codebook) {
...@@ -80,9 +80,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm ...@@ -80,9 +80,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
compressStream.writeShort(vecVal); compressStream.writeShort(vecVal);
} }
} }
final long[] frequencies = quantizer.getFrequencies(); try (final OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerCodebookIndex(), 32)) {
for (final long symbolFrequency : frequencies) { quantizer.getCodebook().getHuffmanTreeRoot().writeToBinaryStream(outBitStream);
compressStream.writeLong(symbolFrequency);
} }
} catch (final IOException ioEx) { } catch (final IOException ioEx) {
throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx); throw new ImageCompressionException("Unable to write codebook to compress stream.", ioEx);
......
...@@ -56,6 +56,7 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I ...@@ -56,6 +56,7 @@ public class VQImageDecompressor extends CompressorDecompressorBase implements I
codebookVectors[codebookIndex][vecIndex] = compressedStream.readUnsignedShort(); 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++) { for (int codebookIndex = 0; codebookIndex < codebookSize; codebookIndex++) {
frequencies[codebookIndex] = compressedStream.readLong(); frequencies[codebookIndex] = compressedStream.readLong();
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment