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

Moved scalar quantization compression to separate file.

parent 260c1b11
No related branches found
No related tags found
No related merge requests found
...@@ -6,9 +6,11 @@ public abstract class CompressorDecompressorBase { ...@@ -6,9 +6,11 @@ public abstract class CompressorDecompressorBase {
public static final String EXTENSTION = ".QCMP"; public static final String EXTENSTION = ".QCMP";
protected final ParsedCliOptions options; protected final ParsedCliOptions options;
protected final int codebookSize;
public CompressorDecompressorBase(ParsedCliOptions options) { public CompressorDecompressorBase(ParsedCliOptions options) {
this.options = options; this.options = options;
this.codebookSize = (int) Math.pow(2, this.options.getBitsPerPixel());
} }
protected int[] getPlaneIndicesForCompression() { protected int[] getPlaneIndicesForCompression() {
......
package azgracompress.compression; package azgracompress.compression;
import azgracompress.cli.ParsedCliOptions; import azgracompress.cli.ParsedCliOptions;
import azgracompress.U16;
import azgracompress.data.Chunk2D; import azgracompress.data.Chunk2D;
import azgracompress.data.ImageU16; import azgracompress.data.ImageU16;
import azgracompress.data.V2i; import azgracompress.data.V2i;
import azgracompress.fileformat.QCMPFileHeader; import azgracompress.fileformat.QCMPFileHeader;
import azgracompress.io.OutBitStream; import azgracompress.io.OutBitStream;
import azgracompress.io.RawDataIO; import azgracompress.io.RawDataIO;
import azgracompress.quantization.scalar.LloydMaxU16ScalarQuantization;
import azgracompress.quantization.scalar.ScalarQuantizer;
import azgracompress.quantization.vector.CodebookEntry; import azgracompress.quantization.vector.CodebookEntry;
import azgracompress.quantization.vector.LBGResult; import azgracompress.quantization.vector.LBGResult;
import azgracompress.quantization.vector.LBGVectorQuantizer; import azgracompress.quantization.vector.LBGVectorQuantizer;
...@@ -43,8 +40,10 @@ public class ImageCompressor extends CompressorDecompressorBase { ...@@ -43,8 +40,10 @@ public class ImageCompressor extends CompressorDecompressorBase {
boolean compressionResult = true; boolean compressionResult = true;
switch (options.getQuantizationType()) { switch (options.getQuantizationType()) {
case Scalar: case Scalar: {
compressUsingScalarQuantization(dataOutputStream); SQImageCompressor compressor = new SQImageCompressor(options);
compressor.compress(dataOutputStream);
}
break; break;
case Vector1D: case Vector1D:
case Vector2D: case Vector2D:
...@@ -62,14 +61,6 @@ public class ImageCompressor extends CompressorDecompressorBase { ...@@ -62,14 +61,6 @@ public class ImageCompressor extends CompressorDecompressorBase {
fos.close(); fos.close();
} }
private ScalarQuantizer getScalarQuantizerFromPlane(final ImageU16 plane) {
LloydMaxU16ScalarQuantization lloydMax = new LloydMaxU16ScalarQuantization(plane.getData(), codebookSize);
lloydMax.train(false);
return new ScalarQuantizer(U16.Min, U16.Max, lloydMax.getCentroids());
}
private int[][] getPlaneVectors(final ImageU16 plane) { private int[][] getPlaneVectors(final ImageU16 plane) {
final V2i qVector = options.getVectorDimension(); final V2i qVector = options.getVectorDimension();
...@@ -153,14 +144,6 @@ public class ImageCompressor extends CompressorDecompressorBase { ...@@ -153,14 +144,6 @@ public class ImageCompressor extends CompressorDecompressorBase {
return header; return header;
} }
private void writeCodebookToOutputStream(final ScalarQuantizer quantizer,
DataOutputStream compressStream) throws IOException {
final int[] centroids = quantizer.getCentroids();
for (final int quantizationValue : centroids) {
compressStream.writeShort(quantizationValue);
}
}
private void writeCodebookToOutputStream(final VectorQuantizer quantizer, private void writeCodebookToOutputStream(final VectorQuantizer quantizer,
DataOutputStream compressStream) throws IOException { DataOutputStream compressStream) throws IOException {
final CodebookEntry[] codebook = quantizer.getCodebook(); final CodebookEntry[] codebook = quantizer.getCodebook();
...@@ -171,44 +154,4 @@ public class ImageCompressor extends CompressorDecompressorBase { ...@@ -171,44 +154,4 @@ public class ImageCompressor extends CompressorDecompressorBase {
} }
} }
} }
private void compressUsingScalarQuantization(DataOutputStream compressStream) throws Exception {
ScalarQuantizer quantizer = null;
if (options.hasReferencePlaneIndex()) {
final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
options.getImageDimension(),
options.getReferencePlaneIndex());
Log("Creating codebook from reference plane...");
quantizer = getScalarQuantizerFromPlane(referencePlane);
writeCodebookToOutputStream(quantizer, compressStream);
Log("Wrote reference codebook.");
}
final int[] planeIndices = getPlaneIndicesForCompression();
for (final int planeIndex : planeIndices) {
Log(String.format("Loading plane %d...", planeIndex));
final ImageU16 plane = RawDataIO.loadImageU16(options.getInputFile(),
options.getImageDimension(),
planeIndex);
if (!options.hasReferencePlaneIndex()) {
Log("Creating plane codebook...");
quantizer = getScalarQuantizerFromPlane(plane);
writeCodebookToOutputStream(quantizer, compressStream);
Log("Wrote plane codebook.");
}
assert (quantizer != null);
Log("Writing quantization indices...");
final int[] indices = quantizer.quantizeIntoIndices(plane.getData());
OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048);
outBitStream.write(indices);
outBitStream.flush();
Log(String.format("Finished processing of plane %d", planeIndex));
}
}
} }
package azgracompress.compression;
import azgracompress.U16;
import azgracompress.cli.ParsedCliOptions;
import azgracompress.data.ImageU16;
import azgracompress.io.OutBitStream;
import azgracompress.io.RawDataIO;
import azgracompress.quantization.scalar.LloydMaxU16ScalarQuantization;
import azgracompress.quantization.scalar.ScalarQuantizer;
import java.io.DataOutputStream;
import java.io.IOException;
public class SQImageCompressor extends CompressorDecompressorBase {
public SQImageCompressor(ParsedCliOptions options) {
super(options);
}
/**
* Train Lloyd-Max scalar quantizer from plane data.
*
* @param planeData Plane data from which quantizer will be trained.
* @return Trained scalar quantizer.
*/
private ScalarQuantizer trainScalarQuantizerFromData(final short[] planeData) {
LloydMaxU16ScalarQuantization lloydMax = new LloydMaxU16ScalarQuantization(planeData, codebookSize);
lloydMax.train(false);
return new ScalarQuantizer(U16.Min, U16.Max, lloydMax.getCentroids());
}
/**
* Writes the scalar quantizer to the compressed stream.
*
* @param quantizer Quantizer used for compression of the image.
* @param compressStream Compressed data stream.
* @throws IOException when writing to the stream fails.
*/
private void writeCodebookToOutputStream(final ScalarQuantizer quantizer,
DataOutputStream compressStream) throws IOException {
final int[] centroids = quantizer.getCentroids();
for (final int quantizationValue : centroids) {
compressStream.writeShort(quantizationValue);
}
}
/**
* Compress the image file specified by parsed CLI options using scalar quantization..
*
* @param compressStream Stream to which compressed data will be written.
* @throws Exception When compress process fails.
*/
public void compress(DataOutputStream compressStream) throws Exception {
ScalarQuantizer quantizer = null;
if (options.hasReferencePlaneIndex()) {
final ImageU16 referencePlane = RawDataIO.loadImageU16(options.getInputFile(),
options.getImageDimension(),
options.getReferencePlaneIndex());
Log("Creating codebook from reference plane...");
quantizer = trainScalarQuantizerFromData(referencePlane.getData());
writeCodebookToOutputStream(quantizer, compressStream);
Log("Wrote reference codebook.");
}
final int[] planeIndices = getPlaneIndicesForCompression();
for (final int planeIndex : planeIndices) {
Log(String.format("Loading plane %d...", planeIndex));
final ImageU16 plane = RawDataIO.loadImageU16(options.getInputFile(),
options.getImageDimension(),
planeIndex);
if (!options.hasReferencePlaneIndex()) {
Log("Creating plane codebook...");
quantizer = trainScalarQuantizerFromData(plane.getData());
writeCodebookToOutputStream(quantizer, compressStream);
Log("Wrote plane codebook.");
}
assert (quantizer != null);
Log("Writing quantization indices...");
final int[] indices = quantizer.quantizeIntoIndices(plane.getData());
OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048);
outBitStream.write(indices);
outBitStream.flush();
Log(String.format("Finished processing of plane %d", planeIndex));
}
}
}
package azgracompress.compression;
public class VQImageCompressor {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment