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

Implement conversion of QVC files.

parent ffd6e09e
No related branches found
No related tags found
No related merge requests found
...@@ -2,6 +2,7 @@ package cz.it4i.qcmp; ...@@ -2,6 +2,7 @@ package cz.it4i.qcmp;
import cz.it4i.qcmp.benchmark.CompressionBenchmark; import cz.it4i.qcmp.benchmark.CompressionBenchmark;
import cz.it4i.qcmp.cache.QuantizationCacheManager; import cz.it4i.qcmp.cache.QuantizationCacheManager;
import cz.it4i.qcmp.cache.QvcFileReader;
import cz.it4i.qcmp.cli.CliConstants; import cz.it4i.qcmp.cli.CliConstants;
import cz.it4i.qcmp.cli.CompressionOptionsCLIParser; import cz.it4i.qcmp.cli.CompressionOptionsCLIParser;
import cz.it4i.qcmp.cli.CustomFunctionBase; import cz.it4i.qcmp.cli.CustomFunctionBase;
...@@ -9,6 +10,7 @@ import cz.it4i.qcmp.cli.functions.DebugFunction; ...@@ -9,6 +10,7 @@ import cz.it4i.qcmp.cli.functions.DebugFunction;
import cz.it4i.qcmp.compression.ImageCompressor; import cz.it4i.qcmp.compression.ImageCompressor;
import cz.it4i.qcmp.compression.ImageDecompressor; import cz.it4i.qcmp.compression.ImageDecompressor;
import cz.it4i.qcmp.fileformat.FileExtensions; import cz.it4i.qcmp.fileformat.FileExtensions;
import cz.it4i.qcmp.fileformat.IQvcFile;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import java.io.IOException; import java.io.IOException;
...@@ -36,24 +38,24 @@ public class DataCompressor { ...@@ -36,24 +38,24 @@ public class DataCompressor {
return; return;
} }
final CompressionOptionsCLIParser compressionOptionsCLIParsed = new CompressionOptionsCLIParser(cmd); final CompressionOptionsCLIParser parsedOptions = new CompressionOptionsCLIParser(cmd);
// NOTE(Moravec): From this point we need to dispose of possible existing SCIFIO context. // NOTE(Moravec): From this point we need to dispose of possible existing SCIFIO context.
if (compressionOptionsCLIParsed.parseError()) { if (parsedOptions.parseError()) {
System.err.println(compressionOptionsCLIParsed.getParseError()); System.err.println(parsedOptions.getParseError());
ScifioWrapper.dispose(); ScifioWrapper.dispose();
return; return;
} }
if (compressionOptionsCLIParsed.isVerbose()) { if (parsedOptions.isVerbose()) {
System.out.println(compressionOptionsCLIParsed.report()); System.out.println(parsedOptions.report());
} }
switch (compressionOptionsCLIParsed.getMethod()) { switch (parsedOptions.getMethod()) {
case Compress: { case Compress: {
final String label = final String label =
compressionOptionsCLIParsed.getQuantizationType().toString() + " " + compressionOptionsCLIParsed.getQuantizationVector().toString(); parsedOptions.getQuantizationType().toString() + " " + parsedOptions.getQuantizationVector().toString();
// final Stopwatch stopwatch = Stopwatch.startNew(); // final Stopwatch stopwatch = Stopwatch.startNew();
final ImageCompressor compressor = new ImageCompressor(compressionOptionsCLIParsed); final ImageCompressor compressor = new ImageCompressor(parsedOptions);
if (!compressor.compress()) { if (!compressor.compress()) {
System.err.println("Errors occurred during compression."); System.err.println("Errors occurred during compression.");
} }
...@@ -66,7 +68,7 @@ public class DataCompressor { ...@@ -66,7 +68,7 @@ public class DataCompressor {
break; break;
case Decompress: { case Decompress: {
// final Stopwatch stopwatch = Stopwatch.startNew(); // final Stopwatch stopwatch = Stopwatch.startNew();
final ImageDecompressor decompressor = new ImageDecompressor(compressionOptionsCLIParsed); final ImageDecompressor decompressor = new ImageDecompressor(parsedOptions);
if (!decompressor.decompressToFile()) { if (!decompressor.decompressToFile()) {
System.err.println("Errors occurred during decompression."); System.err.println("Errors occurred during decompression.");
} }
...@@ -78,11 +80,11 @@ public class DataCompressor { ...@@ -78,11 +80,11 @@ public class DataCompressor {
break; break;
case Benchmark: { case Benchmark: {
CompressionBenchmark.runBenchmark(compressionOptionsCLIParsed); CompressionBenchmark.runBenchmark(parsedOptions);
} }
break; break;
case TrainCodebook: { case TrainCodebook: {
final ImageCompressor compressor = new ImageCompressor(compressionOptionsCLIParsed); final ImageCompressor compressor = new ImageCompressor(parsedOptions);
if (!compressor.trainAndSaveCodebook()) { if (!compressor.trainAndSaveCodebook()) {
System.err.println("Errors occurred during training/saving of codebook."); System.err.println("Errors occurred during training/saving of codebook.");
} }
...@@ -94,7 +96,7 @@ public class DataCompressor { ...@@ -94,7 +96,7 @@ public class DataCompressor {
// final CustomFunctionBase customFunction = new MeasurePlaneErrorFunction(parsedCliOptions); // final CustomFunctionBase customFunction = new MeasurePlaneErrorFunction(parsedCliOptions);
// final CustomFunctionBase customFunction = new EntropyCalculation(compressionOptionsCLIParsed); // final CustomFunctionBase customFunction = new EntropyCalculation(compressionOptionsCLIParsed);
// final CustomFunctionBase cf = new CalculateDifference(compressionOptionsCLIParsed); // final CustomFunctionBase cf = new CalculateDifference(compressionOptionsCLIParsed);
final CustomFunctionBase cf = new DebugFunction(compressionOptionsCLIParsed); final CustomFunctionBase cf = new DebugFunction(parsedOptions);
if (!cf.run()) { if (!cf.run()) {
System.err.println("Errors occurred during custom function."); System.err.println("Errors occurred during custom function.");
} }
...@@ -106,11 +108,11 @@ public class DataCompressor { ...@@ -106,11 +108,11 @@ public class DataCompressor {
} }
break; break;
case InspectFile: { case InspectFile: {
if (compressionOptionsCLIParsed.getInputDataInfo().getFilePath().endsWith(FileExtensions.CACHE_FILE_EXT)) { if (parsedOptions.getInputDataInfo().getFilePath().endsWith(FileExtensions.CACHE_FILE_EXT)) {
QuantizationCacheManager.inspectCacheFile(compressionOptionsCLIParsed.getInputDataInfo().getFilePath(), QuantizationCacheManager.inspectCacheFile(parsedOptions.getInputDataInfo().getFilePath(),
compressionOptionsCLIParsed.isVerbose()); parsedOptions.isVerbose());
} else { } else {
final ImageDecompressor decompressor = new ImageDecompressor(compressionOptionsCLIParsed); final ImageDecompressor decompressor = new ImageDecompressor(parsedOptions);
try { try {
System.out.println(decompressor.inspectCompressedFile()); System.out.println(decompressor.inspectCompressedFile());
} catch (final IOException e) { } catch (final IOException e) {
...@@ -121,7 +123,41 @@ public class DataCompressor { ...@@ -121,7 +123,41 @@ public class DataCompressor {
} }
} }
break; break;
case Convert: {
final boolean inPlace = parsedOptions.getOutputFilePath() == null;
// TODO(Moravec): Maybe replace with generic reader which can determine file type based on magic value and not an extension.
if (parsedOptions.getInputDataInfo().getFilePath().endsWith(FileExtensions.CACHE_FILE_EXT)) {
IQvcFile cacheFile = null;
try {
cacheFile = QvcFileReader.readCacheFile(parsedOptions.getInputDataInfo().getFilePath());
} catch (final IOException e) {
System.err.println("Unable to read QVC file. Error: " + e.getMessage());
exitApplication(1);
}
try {
assert (cacheFile != null);
cacheFile.convertToNewerVersion(inPlace, parsedOptions.getInputDataInfo().getFilePath(),
parsedOptions.getOutputFilePath());
} catch (final IOException e) {
System.err.println("Unable to convert specified QVC file. Error: " + e.getMessage());
exitApplication(1);
}
if (parsedOptions.isVerbose()) {
System.err.println("Qvc file is converted.");
}
} else {
System.err.println("Qcmp file conversion isn't supported yet");
}
}
break;
} }
ScifioWrapper.dispose(); ScifioWrapper.dispose();
} }
private static void exitApplication(final int exitCode) {
ScifioWrapper.dispose();
System.exit(exitCode);
}
} }
...@@ -30,6 +30,9 @@ public class CliConstants { ...@@ -30,6 +30,9 @@ public class CliConstants {
public static final String CUSTOM_FUNCTION_SHORT = "cf"; public static final String CUSTOM_FUNCTION_SHORT = "cf";
public static final String CUSTOM_FUNCTION_LONG = "custom-function"; public static final String CUSTOM_FUNCTION_LONG = "custom-function";
public static final String CONVERT_SHORT = "conv";
public static final String CONVERT_LONG = "convert";
public static final String BITS_SHORT = "b"; public static final String BITS_SHORT = "b";
public static final String BITS_LONG = "bits"; public static final String BITS_LONG = "bits";
...@@ -72,6 +75,10 @@ public class CliConstants { ...@@ -72,6 +75,10 @@ public class CliConstants {
CliConstants.INSPECT_LONG, CliConstants.INSPECT_LONG,
false, false,
"Inspect the compressed file")); "Inspect the compressed file"));
methodGroup.addOption(new Option(CliConstants.CONVERT_SHORT,
CliConstants.CONVERT_LONG,
false,
"Convert input file to new version of custom file format"));
methodGroup.addOption(new Option(CliConstants.BENCHMARK_SHORT, methodGroup.addOption(new Option(CliConstants.BENCHMARK_SHORT,
CliConstants.BENCHMARK_LONG, CliConstants.BENCHMARK_LONG,
......
...@@ -390,6 +390,8 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C ...@@ -390,6 +390,8 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C
method = ProgramMethod.InspectFile; method = ProgramMethod.InspectFile;
} else if (cmd.hasOption(CliConstants.CUSTOM_FUNCTION_LONG)) { } else if (cmd.hasOption(CliConstants.CUSTOM_FUNCTION_LONG)) {
method = ProgramMethod.CustomFunction; method = ProgramMethod.CustomFunction;
} else if (cmd.hasOption(CliConstants.CONVERT_LONG)) {
method = ProgramMethod.Convert;
} else { } else {
parseErrorOccurred = true; parseErrorOccurred = true;
errorBuilder.append("No program method was matched\n"); errorBuilder.append("No program method was matched\n");
...@@ -412,31 +414,7 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C ...@@ -412,31 +414,7 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C
public String report() { public String report() {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("Method: "); sb.append("Method: ").append(method).append('\n');
switch (method) {
case Compress:
sb.append("Compress\n");
break;
case Decompress:
sb.append("Decompress\n");
break;
case Benchmark:
sb.append("Benchmark\n");
break;
case TrainCodebook:
sb.append("TrainCodebook\n");
break;
case PrintHelp:
sb.append("PrintHelp\n");
break;
case CustomFunction:
sb.append("CustomFunction\n");
break;
case InspectFile:
sb.append("InspectFile\n");
break;
}
if (hasQuantizationType(method)) { if (hasQuantizationType(method)) {
sb.append("Quantization type: "); sb.append("Quantization type: ");
...@@ -470,7 +448,6 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C ...@@ -470,7 +448,6 @@ public class CompressionOptionsCLIParser extends CompressionOptions implements C
} }
if (hasQuantizationType(method)) { if (hasQuantizationType(method)) {
sb.append("Input image dims: ").append(getInputDataInfo().getDimensions().toString()).append('\n'); sb.append("Input image dims: ").append(getInputDataInfo().getDimensions().toString()).append('\n');
} }
if (getInputDataInfo().isPlaneIndexSet()) { if (getInputDataInfo().isPlaneIndexSet()) {
......
...@@ -7,5 +7,6 @@ public enum ProgramMethod { ...@@ -7,5 +7,6 @@ public enum ProgramMethod {
TrainCodebook, TrainCodebook,
PrintHelp, PrintHelp,
CustomFunction, CustomFunction,
InspectFile InspectFile,
Convert
} }
...@@ -10,4 +10,6 @@ public interface IQvcHeader extends IFileHeader { ...@@ -10,4 +10,6 @@ public interface IQvcHeader extends IFileHeader {
int getCodebookSize(); int getCodebookSize();
V3i getVectorDim(); V3i getVectorDim();
String getTrainFileName();
} }
...@@ -155,18 +155,22 @@ public class QvcHeaderV1 implements IQvcHeader { ...@@ -155,18 +155,22 @@ public class QvcHeaderV1 implements IQvcHeader {
this.trainFileNameSize = this.trainFileName.length(); this.trainFileNameSize = this.trainFileName.length();
} }
@Override
public QuantizationType getQuantizationType() { public QuantizationType getQuantizationType() {
return quantizationType; return quantizationType;
} }
@Override
public int getCodebookSize() { public int getCodebookSize() {
return codebookSize; return codebookSize;
} }
@Override
public int getBitsPerCodebookIndex() { public int getBitsPerCodebookIndex() {
return (int) Utils.log2(codebookSize); return (int) Utils.log2(codebookSize);
} }
@Override
public String getTrainFileName() { public String getTrainFileName() {
return trainFileName; return trainFileName;
} }
...@@ -183,6 +187,7 @@ public class QvcHeaderV1 implements IQvcHeader { ...@@ -183,6 +187,7 @@ public class QvcHeaderV1 implements IQvcHeader {
return vectorSizeZ; return vectorSizeZ;
} }
@Override
public V3i getVectorDim() { public V3i getVectorDim() {
return new V3i(vectorSizeX, vectorSizeY, vectorSizeZ); return new V3i(vectorSizeX, vectorSizeY, vectorSizeZ);
} }
......
package cz.it4i.qcmp.fileformat; package cz.it4i.qcmp.fileformat;
import cz.it4i.qcmp.cache.QvcFileWriter;
import cz.it4i.qcmp.huffman.HuffmanNode; import cz.it4i.qcmp.huffman.HuffmanNode;
import cz.it4i.qcmp.huffman.HuffmanTreeBuilder; import cz.it4i.qcmp.huffman.HuffmanTreeBuilder;
import cz.it4i.qcmp.io.InBitStream; import cz.it4i.qcmp.io.InBitStream;
...@@ -88,22 +89,18 @@ public class SqQvcFile implements IQvcFile { ...@@ -88,22 +89,18 @@ public class SqQvcFile implements IQvcFile {
codebook = new SQCodebook(centroids, huffmanRoot); codebook = new SQCodebook(centroids, huffmanRoot);
} }
private void convertQvcFromV1ToV2(final String outputFilePath) {
}
@Override @Override
public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) { public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) throws IOException {
final int headerVersion = header.getHeaderVersion();
if (!inPlace && (outputPath == null || outputPath.isEmpty())) { if (!inPlace && (outputPath == null || outputPath.isEmpty())) {
System.err.println("InPlace conversion wasn't specified nor the output file path."); System.err.println("InPlace conversion wasn't specified nor the output file path.");
return; return;
} }
if (headerVersion == 1) { if (header.getHeaderVersion() == 2) {
convertQvcFromV1ToV2(inPlace ? inputPath : outputPath); System.err.print("Version 2 is already the newest version of QVC file.\n");
} else { return;
System.err.printf("Version %d is already the newest version of QVC file.\n", headerVersion);
} }
QvcFileWriter.writeSqCacheFile(inPlace ? inputPath : outputPath, header.getTrainFileName(), codebook);
} }
@Override @Override
......
package cz.it4i.qcmp.fileformat; package cz.it4i.qcmp.fileformat;
import cz.it4i.qcmp.cache.QvcFileWriter;
import cz.it4i.qcmp.huffman.HuffmanNode; import cz.it4i.qcmp.huffman.HuffmanNode;
import cz.it4i.qcmp.huffman.HuffmanTreeBuilder; import cz.it4i.qcmp.huffman.HuffmanTreeBuilder;
import cz.it4i.qcmp.io.InBitStream; import cz.it4i.qcmp.io.InBitStream;
...@@ -97,8 +98,16 @@ public class VqQvcFile implements IQvcFile { ...@@ -97,8 +98,16 @@ public class VqQvcFile implements IQvcFile {
} }
@Override @Override
public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) { public void convertToNewerVersion(final boolean inPlace, final String inputPath, final String outputPath) throws IOException {
assert false : "NOT IMPLEMENTED YET"; if (!inPlace && (outputPath == null || outputPath.isEmpty())) {
System.err.println("InPlace conversion wasn't specified nor the output file path.");
return;
}
if (header.getHeaderVersion() == 2) {
System.err.print("Version 2 is already the newest version of QVC file.\n");
return;
}
QvcFileWriter.writeVqCacheFile(inPlace ? inputPath : outputPath, header.getTrainFileName(), codebook);
} }
@Override @Override
...@@ -111,7 +120,5 @@ public class VqQvcFile implements IQvcFile { ...@@ -111,7 +120,5 @@ public class VqQvcFile implements IQvcFile {
} }
builder.append("\n- - - - - - - - - - - - - - - - - - - - - - - - -\n"); builder.append("\n- - - - - - - - - - - - - - - - - - - - - - - - -\n");
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment