diff --git a/src/main/java/azgracompress/cache/QuantizationCacheManager.java b/src/main/java/azgracompress/cache/QuantizationCacheManager.java
index dbd07c83d947793e49dab0e7e7109627868692a4..d17d3ef9a8ac7a27549df0cb800131233e542dda 100644
--- a/src/main/java/azgracompress/cache/QuantizationCacheManager.java
+++ b/src/main/java/azgracompress/cache/QuantizationCacheManager.java
@@ -2,6 +2,7 @@ package azgracompress.cache;
import azgracompress.data.V3i;
import azgracompress.fileformat.QuantizationType;
+import azgracompress.quantization.QTrainIteration;
import azgracompress.quantization.scalar.SQCodebook;
import azgracompress.quantization.vector.VQCodebook;
@@ -36,7 +37,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 +53,7 @@ public class QuantizationCacheManager {
final V3i vDim) {
final File inputFile = new File(trainFile);
return new File(cacheFolder, String.format("%s_%d_%dx%d.qvc", inputFile.getName(), codebookSize,
- vDim.getX(), vDim.getY()));
+ vDim.getX(), vDim.getY()));
}
@@ -140,8 +141,8 @@ public class QuantizationCacheManager {
*/
public void 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);
@@ -172,15 +173,38 @@ public class QuantizationCacheManager {
}
}
+ /**
+ * Check if the SQ cache file for given image file exists.
+ *
+ * @param imageFile Image file.
+ * @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) {
+ return getCacheFilePathForSQ(imageFile, codebookSize).exists();
+ }
+
+ /**
+ * Check if the VQ cache file for given image file exists.
+ *
+ * @param imageFile Image file.
+ * @param codebookSize Scalar quantization codebook size.
+ * @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) {
+ return getCacheFilePathForVQ(imageFile, codebookSize, vDim).exists();
+ }
+
/**
* Load SQ cache file from disk.
*
- * @param trainFile Input image file.
+ * @param imageFile Input image file.
* @param codebookSize Codebook size.
* @return SQ cache file.
*/
- private SQCacheFile loadSQCacheFile(final String trainFile, final int codebookSize) {
- final File path = getCacheFilePathForSQ(trainFile, codebookSize);
+ private SQCacheFile loadSQCacheFile(final String imageFile, final int codebookSize) {
+ final File path = getCacheFilePathForSQ(imageFile, codebookSize);
try {
return (SQCacheFile) readCacheFile(path, new SQCacheFile());
} catch (IOException e) {
@@ -293,4 +317,6 @@ public class QuantizationCacheManager {
sb.append('\n');
System.out.println(sb.toString());
}
+
+
}
diff --git a/src/main/java/azgracompress/cli/ParsedCliOptions.java b/src/main/java/azgracompress/cli/ParsedCliOptions.java
index 1ff3dfe5242e1d5e517ac1f376d9b412674103d1..d46ead03fc43393047459015858407776b209369 100644
--- a/src/main/java/azgracompress/cli/ParsedCliOptions.java
+++ b/src/main/java/azgracompress/cli/ParsedCliOptions.java
@@ -149,10 +149,14 @@ public class ParsedCliOptions extends CompressionOptions implements Cloneable {
}
if (!parseErrorOccurred) {
- setOutputFilePath(cmd.getOptionValue(CliConstants.OUTPUT_LONG, getDefaultOutputFilePath(((FileInputData) getInputDataInfo()).getFilePath())));
+ setOutputFilePath(cmd.getOptionValue(CliConstants.OUTPUT_LONG, getDefaultOutputFilePath(getInputDataInfo().getFilePath())));
setCodebookCacheFolder(cmd.getOptionValue(CliConstants.CODEBOOK_CACHE_FOLDER_LONG, null));
}
+ if (getMethod() == ProgramMethod.TrainCodebook) {
+ setCodebookCacheFolder(getOutputFilePath());
+ }
+
parseError = errorBuilder.toString();
}
diff --git a/src/main/java/azgracompress/compression/SQImageCompressor.java b/src/main/java/azgracompress/compression/SQImageCompressor.java
index 598f231bbb93df1ddeebe29f3f190119f3d37924..7a3b067ed5ebb7bcf9df5b1391c4f55faddbb81e 100644
--- a/src/main/java/azgracompress/compression/SQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/SQImageCompressor.java
@@ -73,8 +73,11 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
private ScalarQuantizer loadQuantizerFromCache() throws ImageCompressionException {
QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder());
- final SQCodebook codebook = cacheManager.loadSQCodebook(options.getInputDataInfo().getFilePath(),
- getCodebookSize());
+ if (!cacheManager.doesSQCacheExists(options.getInputDataInfo().getCacheFileName(), getCodebookSize())) {
+ trainAndSaveCodebook();
+ }
+
+ final SQCodebook codebook = cacheManager.loadSQCodebook(options.getInputDataInfo().getCacheFileName(), getCodebookSize());
if (codebook == null) {
throw new ImageCompressionException("Failed to read quantization values from cache file.");
}
@@ -220,9 +223,9 @@ public class SQImageCompressor extends CompressorDecompressorBase implements IIm
Log("Finished LloydMax training.");
Log(String.format("Saving cache file to %s", options.getOutputFilePath()));
- QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getOutputFilePath());
+ QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder());
try {
- cacheManager.saveCodebook(options.getInputDataInfo().getFilePath(), codebook);
+ cacheManager.saveCodebook(options.getInputDataInfo().getCacheFileName(), codebook);
} 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 e1f89b4768f84d88639252cbc14cb049da419599..d94984ca218d9262c006f50ea468e90f0acbfe0c 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -75,10 +75,16 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder());
+ if (!cacheManager.doesVQCacheExists(options.getInputDataInfo().getCacheFileName(),
+ getCodebookSize(),
+ options.getVectorDimension().toV3i())) {
+ trainAndSaveCodebook();
+ }
+
+ final VQCodebook codebook = cacheManager.loadVQCodebook(options.getInputDataInfo().getCacheFileName(),
+ getCodebookSize(),
+ options.getVectorDimension().toV3i());
- final VQCodebook codebook = cacheManager.loadVQCodebook(options.getInputDataInfo().getFilePath(),
- getCodebookSize(),
- options.getVectorDimension().toV3i());
if (codebook == null) {
throw new ImageCompressionException("Failed to read quantization vectors from cache.");
}
@@ -230,10 +236,10 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
}
System.arraycopy(planeVectors,
- 0,
- trainData,
- (planeCounter * chunkCountPerPlane),
- chunkCountPerPlane);
+ 0,
+ trainData,
+ (planeCounter * chunkCountPerPlane),
+ chunkCountPerPlane);
++planeCounter;
}
}
@@ -256,9 +262,9 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
Log("Saving cache file to %s", options.getOutputFilePath());
- QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getOutputFilePath());
+ QuantizationCacheManager cacheManager = new QuantizationCacheManager(options.getCodebookCacheFolder());
try {
- cacheManager.saveCodebook(options.getInputDataInfo().getFilePath(), lbgResult.getCodebook());
+ cacheManager.saveCodebook(options.getInputDataInfo().getCacheFileName(), lbgResult.getCodebook());
} catch (IOException e) {
throw new ImageCompressionException("Unable to write VQ cache.", e);
}
diff --git a/src/main/java/azgracompress/io/BufferInputData.java b/src/main/java/azgracompress/io/BufferInputData.java
index 9ab179dac8c57104e8f4a964ef13463f6cffba4c..3d0223aa4f1aec6b3e1975570d529caae382b151 100644
--- a/src/main/java/azgracompress/io/BufferInputData.java
+++ b/src/main/java/azgracompress/io/BufferInputData.java
@@ -12,6 +12,7 @@ public class BufferInputData extends InputData {
*/
private final Object[] imageBuffers;
+ private final String cacheHint;
/**
* Create input data backed by buffer object.
@@ -19,12 +20,17 @@ public class BufferInputData extends InputData {
* @param imageBuffers Image buffer references.
* @param imageDimensions Image dimensions.
* @param pixelType Image pixel type.
+ * @param cacheHint Name of the image used in caching.
*/
- public BufferInputData(final Object[] imageBuffers, final V3i imageDimensions, final PixelType pixelType) {
+ public BufferInputData(final Object[] imageBuffers,
+ final V3i imageDimensions,
+ final PixelType pixelType,
+ final String cacheHint) {
this.imageBuffers = imageBuffers;
setDataLoaderType(DataLoaderType.ImageJBufferLoader);
setDimension(imageDimensions);
setPixelType(pixelType);
+ this.cacheHint = cacheHint;
}
/**
@@ -38,4 +44,9 @@ public class BufferInputData extends InputData {
assert (planeIndex < imageBuffers.length);
return imageBuffers[planeIndex];
}
+
+ @Override
+ public String getCacheFileName() {
+ return cacheHint;
+ }
}
diff --git a/src/main/java/azgracompress/io/FileInputData.java b/src/main/java/azgracompress/io/FileInputData.java
index 49fad663a4d9653f3647cbc24949ba660416f219..968fbd66d7a2302d61e2added34382470e7a0d30 100644
--- a/src/main/java/azgracompress/io/FileInputData.java
+++ b/src/main/java/azgracompress/io/FileInputData.java
@@ -12,6 +12,7 @@ public class FileInputData extends InputData {
/**
* Create input data backed by data file.
+ *
* @param filePath
*/
public FileInputData(String filePath) {
@@ -20,10 +21,16 @@ public class FileInputData extends InputData {
/**
* Get path to the data file.
+ *
* @return
*/
@Override
public String getFilePath() {
return filePath;
}
+
+ @Override
+ public String getCacheFileName() {
+ return filePath;
+ }
}
diff --git a/src/main/java/azgracompress/io/InputData.java b/src/main/java/azgracompress/io/InputData.java
index f4a27a9bb87b31ea373e34430382fcf4591ce5d9..966a706e8a63b019776616e4a78abb8565dfdaa1 100644
--- a/src/main/java/azgracompress/io/InputData.java
+++ b/src/main/java/azgracompress/io/InputData.java
@@ -97,9 +97,17 @@ public abstract class InputData {
/**
* Override in FileInputData!!!
+ *
* @return null!
*/
public String getFilePath() {
return null;
}
+
+ /**
+ * Get name used in creation of qcmp cache file.
+ *
+ * @return Name used for cache file.
+ */
+ public abstract String getCacheFileName();
}