From 857044575575b4a6aba4965033dcddcdd59e0e40 Mon Sep 17 00:00:00 2001 From: Vojtech Moravec <vojtech.moravec.st@vsb.cz> Date: Wed, 2 Dec 2020 14:20:06 +0100 Subject: [PATCH] Read new version of QVC files in QuantizationCacheManager. --- .../qcmp/cache/QuantizationCacheManager.java | 180 +++--------------- .../cz/it4i/qcmp/cache/QvcFileReader.java | 2 + .../qcmp/compression/SQImageCompressor.java | 2 +- .../qcmp/compression/VQImageCompressor.java | 6 +- 4 files changed, 37 insertions(+), 153 deletions(-) diff --git a/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java b/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java index c381c68..9665e73 100644 --- a/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java +++ b/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java @@ -3,11 +3,14 @@ package cz.it4i.qcmp.cache; import cz.it4i.qcmp.compression.CompressionOptions; import cz.it4i.qcmp.data.V3i; import cz.it4i.qcmp.fileformat.QuantizationType; -import cz.it4i.qcmp.fileformat.QvcHeaderV1; +import cz.it4i.qcmp.fileformat.QvcHeaderV2; import cz.it4i.qcmp.quantization.scalar.SQCodebook; import cz.it4i.qcmp.quantization.vector.VQCodebook; -import java.io.*; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.ArrayList; @@ -37,8 +40,7 @@ public class QuantizationCacheManager { */ private File getCacheFilePathForSQ(final String trainFile, final int codebookSize) { final File inputFile = new File(trainFile); - return new File(cacheFolder, String.format("%s_%d_bits.qvc", - inputFile.getName(), codebookSize)); + return new File(cacheFolder, String.format("%s_%d_bits.qvc", inputFile.getName(), codebookSize)); } /** @@ -53,9 +55,8 @@ public class QuantizationCacheManager { final int codebookSize, final V3i vDim) { final File inputFile = new File(trainFile); - final String cacheFileName = String.format("%s_%d_%dx%dx%d.qvc", inputFile.getName(), codebookSize, - vDim.getX(), vDim.getY(), vDim.getZ()); - // System.out.println("getCacheFilePathForVQ()=" + cacheFileName); + final String cacheFileName = String.format("%s_%d_%dx%dx%d.qvc", inputFile.getName(), + codebookSize, vDim.getX(), vDim.getY(), vDim.getZ()); return new File(cacheFolder, cacheFileName); } @@ -67,8 +68,8 @@ public class QuantizationCacheManager { * @param codebook Final SQ codebook. * @return SQ cache file header. */ - private QvcHeaderV1 createHeaderForSQ(final String trainFile, final SQCodebook codebook) { - final QvcHeaderV1 header = new QvcHeaderV1(); + private QvcHeaderV2 createHeaderForSQ(final String trainFile, final SQCodebook codebook) { + final QvcHeaderV2 header = new QvcHeaderV2(); header.setQuantizationType(QuantizationType.Scalar); header.setCodebookSize(codebook.getCodebookSize()); header.setTrainFileName(trainFile); @@ -104,8 +105,8 @@ public class QuantizationCacheManager { * @param codebook Final VQ codebook. * @return VQ cache file header. */ - private QvcHeaderV1 createHeaderForVQ(final String trainFile, final VQCodebook codebook) { - final QvcHeaderV1 header = new QvcHeaderV1(); + private QvcHeaderV2 createHeaderForVQ(final String trainFile, final VQCodebook codebook) { + final QvcHeaderV2 header = new QvcHeaderV2(); header.setQuantizationType(getQuantizationTypeFromVectorDimensions(codebook.getVectorDims())); header.setCodebookSize(codebook.getCodebookSize()); header.setTrainFileName(trainFile); @@ -124,7 +125,7 @@ public class QuantizationCacheManager { public String saveCodebook(final String trainFile, final SQCodebook codebook) throws IOException { final String fileName = getCacheFilePathForSQ(trainFile, codebook.getCodebookSize()).getAbsolutePath(); - final QvcHeaderV1 header = createHeaderForSQ(new File(trainFile).getName(), codebook); + final QvcHeaderV2 header = createHeaderForSQ(new File(trainFile).getName(), codebook); final SqQvcFile cacheFile = new SqQvcFile(header, codebook); try (final FileOutputStream fos = new FileOutputStream(fileName, false); @@ -132,7 +133,7 @@ public class QuantizationCacheManager { cacheFile.writeToStream(dos); } catch (final IOException ex) { - throw new IOException("Failed to save SQ cache file\n" + ex.getMessage()); + throw new IOException("Failed to save SQ QVC file\n" + ex.getMessage()); } return fileName; } @@ -151,7 +152,7 @@ public class QuantizationCacheManager { codebook.getCodebookSize(), codebook.getVectorDims()).getAbsolutePath(); - final QvcHeaderV1 header = createHeaderForVQ(new File(trainFile).getName(), codebook); + final QvcHeaderV2 header = createHeaderForVQ(new File(trainFile).getName(), codebook); final VqQvcFile cacheFile = new VqQvcFile(header, codebook); try (final FileOutputStream fos = new FileOutputStream(fileName, false); @@ -164,23 +165,6 @@ public class QuantizationCacheManager { return fileName; } - /** - * Read data from file to cache file. - * - * @param file Cache file. - * @param cacheFile Actual cache file object. - * @return Cache file with data from disk. - * @throws IOException when fails to read the cache file from disk. - */ - private IQvcFile readCacheFile(final File file, final IQvcFile cacheFile) throws IOException { - try (final FileInputStream fis = new FileInputStream(file); - final DataInputStream dis = new DataInputStream(fis)) { - - cacheFile.readFromStream(dis); - return cacheFile; - } - } - /** * Check if the SQ cache file for given image file exists. * @@ -188,7 +172,7 @@ public class QuantizationCacheManager { * @param codebookSize Scalar quantization codebook size. * @return True if cache file exists and and can be loaded. */ - public boolean doesSQCacheExists(final String imageFile, final int codebookSize) { + public boolean doesSqQvcFileExists(final String imageFile, final int codebookSize) { return getCacheFilePathForSQ(imageFile, codebookSize).exists(); } @@ -200,7 +184,7 @@ public class QuantizationCacheManager { * @param vDim Quantization vector dimensions. * @return True if cache file exists and and can be loaded. */ - public boolean doesVQCacheExists(final String imageFile, final int codebookSize, final V3i vDim) { + public boolean doesVqQvcFileExists(final String imageFile, final int codebookSize, final V3i vDim) { return getCacheFilePathForVQ(imageFile, codebookSize, vDim).exists(); } @@ -212,14 +196,8 @@ public class QuantizationCacheManager { * @return SQ cache file. */ public SqQvcFile loadSQCacheFile(final String imageFile, final int codebookSize) { - final File path = getCacheFilePathForSQ(imageFile, codebookSize); - try { - return (SqQvcFile) readCacheFile(path, new SqQvcFile()); - } catch (final IOException e) { - System.err.println("Failed to read SQ cache file." + path); - e.printStackTrace(System.err); - return null; - } + final File fileInfo = getCacheFilePathForSQ(imageFile, codebookSize); + return (SqQvcFile) QvcFileReader.readCacheFile(fileInfo.getAbsolutePath()); } /** @@ -233,14 +211,8 @@ public class QuantizationCacheManager { public VqQvcFile loadVQCacheFile(final String trainFile, final int codebookSize, final V3i vDim) { - final File path = getCacheFilePathForVQ(trainFile, codebookSize, vDim); - try { - return (VqQvcFile) readCacheFile(path, new VqQvcFile()); - } catch (final IOException e) { - System.err.println("Failed to read VQ cache file." + path); - e.printStackTrace(System.err); - return null; - } + final File fileInfo = getCacheFilePathForVQ(trainFile, codebookSize, vDim); + return (VqQvcFile) QvcFileReader.readCacheFile(fileInfo.getAbsolutePath()); } /** @@ -277,17 +249,6 @@ public class QuantizationCacheManager { } - private static IQvcFile getCacheFile(final QuantizationType qt) { - if (qt.isOneOf(QuantizationType.Vector1D, QuantizationType.Vector2D, QuantizationType.Vector3D)) - return new VqQvcFile(); - else if (qt == QuantizationType.Scalar) - return new SqQvcFile(); - - assert (false) : "Invalid quantization type."; - return null; - } - - /** * Tries to load all (different codebook sizes) available cache files for given file and quantization type. * @@ -339,110 +300,31 @@ public class QuantizationCacheManager { default: return null; } - return readCacheFile(path); - } - - /** - * Read cache file by DataInputStream. - * - * @param inputStream Input stream. - * @return Cache file or null, if exception occurs. - */ - private static IQvcFile readCacheFileImpl(final InputStream inputStream) { - final DataInputStream dis; - if (inputStream instanceof DataInputStream) { - dis = (DataInputStream) inputStream; - } else { - dis = new DataInputStream(inputStream); - } - final QvcHeaderV1 header = new QvcHeaderV1(); - try { - header.readFromStream(dis); - } catch (final IOException e) { - System.err.println("Failed to read CacheFileHeader from input stream"); - e.printStackTrace(); - return null; - } - - final IQvcFile cacheFile = getCacheFile(header.getQuantizationType()); - assert (cacheFile != null); - try { - cacheFile.readFromStream(dis, header); - } catch (final IOException e) { - System.err.println("Failed to read cache file from input stream."); - e.printStackTrace(); - return null; - } - return cacheFile; - } - - /** - * Read cache file from input stream. - * - * @param inputStream Input data stream. - * @return Cache file or null if reading fails. - */ - public static IQvcFile readCacheFile(final InputStream inputStream) { - return readCacheFileImpl(inputStream); + return QvcFileReader.readCacheFile(path); } - /** - * Read cache file from file. - * - * @param path File path. - * @return Cache file or null if reading fails. - */ - public static IQvcFile readCacheFile(final String path) { - try (final FileInputStream fis = new FileInputStream(path)) { - return readCacheFileImpl(fis); - } catch (final IOException e) { - return null; - } - } - /** * Inspect cache file specified by the path. * * @param path Path to cache file. */ public static void inspectCacheFile(final String path, final boolean verbose) { - QvcHeaderV1 header = null; - final long fileSize; - try (final FileInputStream fis = new FileInputStream(path); - final DataInputStream dis = new DataInputStream(fis)) { - fileSize = fis.getChannel().size(); - header = new QvcHeaderV1(); - header.readFromStream(dis); - } catch (final IOException e) { - e.printStackTrace(); + final IQvcFile qvcFile = QvcFileReader.readCacheFile(path); + if (qvcFile == null) { + System.err.println("Provided path is not of valid QVC file."); return; } - final StringBuilder reportBuilder = new StringBuilder(); - final long expectedFileSize = header.getExpectedDataSize(); - if (expectedFileSize == fileSize) { - reportBuilder.append("\u001B[32mCache file is VALID ").append(fileSize).append(" bytes\u001B[0m\n"); - } else { - reportBuilder.append("\u001B[31mCache file is INVALID.\u001B[0m\n\t") - .append(fileSize).append(" bytes instead of expected ") - .append(expectedFileSize).append(" bytes.\n"); + if (!qvcFile.getHeader().validateHeader()) { + System.err.println("Provided file is corrupted."); + return; } - header.report(reportBuilder, path); + final StringBuilder reportBuilder = new StringBuilder(); + qvcFile.getHeader().report(reportBuilder, path); if (verbose) { - - final IQvcFile cacheFile = getCacheFile(header.getQuantizationType()); - assert (cacheFile != null); - - try (final FileInputStream fis = new FileInputStream(path); - final DataInputStream dis = new DataInputStream(fis)) { - cacheFile.readFromStream(dis); - } catch (final Exception e) { - reportBuilder.append(e.getMessage()); - } - - cacheFile.report(reportBuilder); + qvcFile.report(reportBuilder); } System.out.println(reportBuilder); diff --git a/src/main/java/cz/it4i/qcmp/cache/QvcFileReader.java b/src/main/java/cz/it4i/qcmp/cache/QvcFileReader.java index 834397d..3587714 100644 --- a/src/main/java/cz/it4i/qcmp/cache/QvcFileReader.java +++ b/src/main/java/cz/it4i/qcmp/cache/QvcFileReader.java @@ -24,6 +24,8 @@ public class QvcFileReader { try (final FileInputStream fis = new FileInputStream(path)) { return readCacheFileImpl(fis); } catch (final IOException e) { + System.err.println(e.getMessage()); + e.printStackTrace(); return null; } } diff --git a/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java b/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java index effc516..aee6464 100644 --- a/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/SQImageCompressor.java @@ -84,7 +84,7 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm private ScalarQuantizer loadQuantizerFromCache() throws ImageCompressionException { final QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder()); - if (!cacheManager.doesSQCacheExists(options.getInputDataInfo().getCacheFileName(), getCodebookSize())) { + if (!cacheManager.doesSqQvcFileExists(options.getInputDataInfo().getCacheFileName(), getCodebookSize())) { trainAndSaveCodebook(); } diff --git a/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java b/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java index b273f83..0bdd52f 100644 --- a/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java +++ b/src/main/java/cz/it4i/qcmp/compression/VQImageCompressor.java @@ -101,9 +101,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm private VectorQuantizer loadQuantizerFromCache() throws ImageCompressionException { final QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder()); - if (!cacheManager.doesVQCacheExists(options.getInputDataInfo().getCacheFileName(), - getCodebookSize(), - options.getQuantizationVector())) { + if (!cacheManager.doesVqQvcFileExists(options.getInputDataInfo().getCacheFileName(), + getCodebookSize(), + options.getQuantizationVector())) { reportStatusToListeners("Codebook cache not found."); trainAndSaveCodebook(); } -- GitLab