diff --git a/src/main/java/azgracompress/cache/QuantizationCacheManager.java b/src/main/java/azgracompress/cache/QuantizationCacheManager.java index 8ff01040610cb1beb6ddc2734879c21dc5582b2c..73858a75397f32bec411580f015a3df20806b403 100644 --- a/src/main/java/azgracompress/cache/QuantizationCacheManager.java +++ b/src/main/java/azgracompress/cache/QuantizationCacheManager.java @@ -36,7 +36,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)); + inputFile.getName(), codebookSize)); } /** @@ -52,7 +52,7 @@ public class QuantizationCacheManager { final V3i vDim) { final File inputFile = new File(trainFile); return new File(cacheFolder, String.format("%s_%d_%dx%dx%d.qvc", inputFile.getName(), codebookSize, - vDim.getX(), vDim.getY(), vDim.getZ())); + vDim.getX(), vDim.getY(), vDim.getZ())); } @@ -114,9 +114,10 @@ public class QuantizationCacheManager { * * @param trainFile Image file used for training. * @param codebook SQ codebook. + * @return Path to the saved cache file. * @throws IOException when fails to save the cache file. */ - public void saveCodebook(final String trainFile, final SQCodebook codebook) throws IOException { + public String saveCodebook(final String trainFile, final SQCodebook codebook) throws IOException { final String fileName = getCacheFilePathForSQ(trainFile, codebook.getCodebookSize()).getAbsolutePath(); final CacheFileHeader header = createHeaderForSQ(new File(trainFile).getName(), codebook); @@ -129,6 +130,7 @@ public class QuantizationCacheManager { } catch (IOException ex) { throw new IOException("Failed to save SQ cache file\n" + ex.getMessage()); } + return fileName; } /** @@ -136,12 +138,13 @@ public class QuantizationCacheManager { * * @param trainFile Image file used for training. * @param codebook VQ codebook. + * @return Path to the saved cache file. * @throws IOException when fails to save the cache file. */ - public void saveCodebook(final String trainFile, final VQCodebook codebook) throws IOException { + public String saveCodebook(final String trainFile, final VQCodebook codebook) throws IOException { final String fileName = getCacheFilePathForVQ(trainFile, - codebook.getCodebookSize(), - codebook.getVectorDims()).getAbsolutePath(); + codebook.getCodebookSize(), + codebook.getVectorDims()).getAbsolutePath(); final CacheFileHeader header = createHeaderForVQ(new File(trainFile).getName(), codebook); final VQCacheFile cacheFile = new VQCacheFile(header, codebook); @@ -153,6 +156,7 @@ public class QuantizationCacheManager { } catch (IOException ex) { throw new IOException("Failed to save VQ cache file\n" + ex.getMessage()); } + return fileName; } /** diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java index ee07010a821bd8abdd4e98a7fb29519651e3d81b..c000e44e48355b350f199997f65daca7c2b87c46 100644 --- a/src/main/java/azgracompress/compression/SQImageCompressor.java +++ b/src/main/java/azgracompress/compression/SQImageCompressor.java @@ -30,8 +30,8 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm private ScalarQuantizer trainScalarQuantizerFromData(final int[] planeData) { LloydMaxU16ScalarQuantization lloydMax = new LloydMaxU16ScalarQuantization(planeData, - getCodebookSize(), - options.getWorkerCount()); + getCodebookSize(), + options.getWorkerCount()); lloydMax.train(); return new ScalarQuantizer(U16.Min, U16.Max, lloydMax.getCodebook()); } @@ -77,7 +77,7 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm } final SQCodebook codebook = cacheManager.loadSQCodebook(options.getInputDataInfo().getCacheFileName(), - getCodebookSize()); + getCodebookSize()); if (codebook == null) { throw new ImageCompressionException("Failed to read quantization values from cache file."); } @@ -164,7 +164,7 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm stopwatch.stop(); reportProgressToListeners(planeIndex, planeIndices.length, - "Compressed plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString()); + "Compressed plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString()); } return planeDataSizes; } @@ -212,8 +212,8 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm LloydMaxU16ScalarQuantization lloydMax = new LloydMaxU16ScalarQuantization(trainData, - getCodebookSize(), - options.getWorkerCount()); + getCodebookSize(), + options.getWorkerCount()); reportStatusToListeners("Starting LloydMax training."); lloydMax.setStatusListener(this::reportStatusToListeners); @@ -221,10 +221,10 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm final SQCodebook codebook = lloydMax.getCodebook(); reportStatusToListeners("Finished LloydMax training."); - reportStatusToListeners(String.format("Saving cache file to %s", options.getOutputFilePath())); QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder()); try { - cacheManager.saveCodebook(options.getInputDataInfo().getCacheFileName(), codebook); + final String cacheFilePath = cacheManager.saveCodebook(options.getInputDataInfo().getCacheFileName(), codebook); + reportStatusToListeners(String.format("Saved cache file to %s", cacheFilePath)); } catch (IOException e) { throw new ImageCompressionException("Unable to write cache.", e); } diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java index c5b4ec0d242da075783e4a8db2667bd8b83dc9fc..bc302b1a81eb742b680cd98b8b26fab98b98b3cf 100644 --- a/src/main/java/azgracompress/compression/VQImageCompressor.java +++ b/src/main/java/azgracompress/compression/VQImageCompressor.java @@ -32,9 +32,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm private VectorQuantizer trainVectorQuantizerFromPlaneVectors(final int[][] planeVectors) { LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(planeVectors, - getCodebookSize(), - options.getWorkerCount(), - options.getQuantizationVector()); + getCodebookSize(), + options.getWorkerCount(), + options.getQuantizationVector()); LBGResult vqResult = vqInitializer.findOptimalCodebook(); return new VectorQuantizer(vqResult.getCodebook()); } @@ -79,14 +79,14 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder()); if (!cacheManager.doesVQCacheExists(options.getInputDataInfo().getCacheFileName(), - getCodebookSize(), - options.getQuantizationVector())) { + getCodebookSize(), + options.getQuantizationVector())) { trainAndSaveCodebook(); } final VQCodebook codebook = cacheManager.loadVQCodebook(options.getInputDataInfo().getCacheFileName(), - getCodebookSize(), - options.getQuantizationVector()); + getCodebookSize(), + options.getQuantizationVector()); if (codebook == null) { throw new ImageCompressionException("Failed to read quantization vectors from cache."); @@ -182,7 +182,7 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm stopwatch.stop(); reportProgressToListeners(planeIndex, planeIndices.length, - "Finished compression of plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString()); + "Finished compression of plane %d in %s.", planeIndex, stopwatch.getElapsedTimeString()); } return planeDataSizes; } @@ -226,11 +226,11 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm } } else { reportStatusToListeners(options.getInputDataInfo().isPlaneRangeSet() ? - "VQ: Loading plane range data." : "VQ: Loading all planes data."); + "VQ: Loading plane range data." : "VQ: Loading all planes data."); final int[] planeIndices = getPlaneIndicesForCompression(); final int chunkCountPerPlane = Chunk2D.calculateRequiredChunkCount(options.getInputDataInfo().getDimensions().toV2i(), - options.getQuantizationVector().toV2i()); + options.getQuantizationVector().toV2i()); final int totalChunkCount = chunkCountPerPlane * planeIndices.length; trainData = new int[totalChunkCount][vectorSize]; @@ -254,7 +254,7 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm } else { if (options.getQuantizationType() != QuantizationType.Vector3D) { throw new ImageCompressionException("Invalid QuantizationType, expected: `QuantizationType.Vector3D`, but got: " + - options.getQuantizationType().toString()); + options.getQuantizationType().toString()); } try { @@ -271,9 +271,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm final int[][] trainingData = loadConfiguredPlanesData(); LBGVectorQuantizer vqInitializer = new LBGVectorQuantizer(trainingData, - getCodebookSize(), - options.getWorkerCount(), - options.getQuantizationVector()); + getCodebookSize(), + options.getWorkerCount(), + options.getQuantizationVector()); reportStatusToListeners("Starting LBG optimization."); vqInitializer.setStatusListener(this::reportStatusToListeners); @@ -281,10 +281,10 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm reportStatusToListeners("Learned the optimal codebook."); - reportStatusToListeners("Saving cache file to %s", options.getOutputFilePath()); QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder()); try { - cacheManager.saveCodebook(options.getInputDataInfo().getCacheFileName(), lbgResult.getCodebook()); + final String cacheFilePath = cacheManager.saveCodebook(options.getInputDataInfo().getCacheFileName(), lbgResult.getCodebook()); + reportStatusToListeners("Saved cache file to %s", cacheFilePath); } catch (IOException e) { throw new ImageCompressionException("Unable to write VQ cache.", e); } @@ -346,8 +346,8 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm voxelLayersSizes[voxelLayerIndex] = writeHuffmanEncodedIndices(compressStream, huffman, indices); stopwatch.stop(); reportProgressToListeners(voxelLayerIndex, voxelLayerCount, - "%d/%d Finished voxel layer %s compression pass in %s", - voxelLayerIndex, voxelLayerCount, voxelLayerRange.toString(), stopwatch.getElapsedTimeString()); + "%d/%d Finished voxel layer %s compression pass in %s", + voxelLayerIndex, voxelLayerCount, voxelLayerRange.toString(), stopwatch.getElapsedTimeString()); } return voxelLayersSizes;