diff --git a/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java b/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java index b63d0ac80af5032e9ddcfe47f122ed17718f932e..b01c051fd459c83137ddc7ab69557bda5bdac91b 100644 --- a/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java +++ b/src/main/java/cz/it4i/qcmp/cache/QuantizationCacheManager.java @@ -2,13 +2,13 @@ package cz.it4i.qcmp.cache; import cz.it4i.qcmp.compression.CompressionOptions; import cz.it4i.qcmp.data.V3i; -import cz.it4i.qcmp.fileformat.*; +import cz.it4i.qcmp.fileformat.IQvcFile; +import cz.it4i.qcmp.fileformat.SqQvcFile; +import cz.it4i.qcmp.fileformat.VqQvcFile; import cz.it4i.qcmp.quantization.scalar.SQCodebook; import cz.it4i.qcmp.quantization.vector.VQCodebook; -import java.io.DataOutputStream; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -59,62 +59,8 @@ public class QuantizationCacheManager { return new File(cacheFolder, cacheFileName); } - - /** - * Create CacheFileHeader for ScalarQuantization cache. - * - * @param trainFile Image file used for training. - * @param codebook Final SQ codebook. - * @return SQ cache file header. - */ - 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); - header.setVectorDims(new V3i(0)); - return header; - } - - /** - * Find the correct quantization type based on vector dimension. - * - * @param vectorDims Quantization vector dimensions. - * @return Correct QuantizationType. - */ - private QuantizationType getQuantizationTypeFromVectorDimensions(final V3i vectorDims) { - if (vectorDims.getX() > 1) { - if (vectorDims.getY() == 1 && vectorDims.getZ() == 1) { - return QuantizationType.Vector1D; - } else if (vectorDims.getY() > 1 && vectorDims.getZ() == 1) { - return QuantizationType.Vector2D; - } else { - return QuantizationType.Vector3D; - } - } else if (vectorDims.getX() == 1 && vectorDims.getY() > 1 && vectorDims.getZ() == 1) { - return QuantizationType.Vector1D; - } - return QuantizationType.Invalid; - } - /** - * Create CacheFileHeader for VQ cache. - * - * @param trainFile Image file used for training. - * @param codebook Final VQ codebook. - * @return VQ cache file header. - */ - 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); - header.setVectorDims(codebook.getVectorDims()); - return header; - } - - /** - * Save SQ codebook to cache. + * Save SQ codebook to disk cache. * * @param trainFile Image file used for training. * @param codebook SQ codebook. @@ -122,19 +68,9 @@ public class QuantizationCacheManager { * @throws IOException when fails to save the cache file. */ public String saveCodebook(final String trainFile, final SQCodebook codebook) throws IOException { - final String fileName = getCacheFilePathForSQ(trainFile, codebook.getCodebookSize()).getAbsolutePath(); - - final QvcHeaderV2 header = createHeaderForSQ(new File(trainFile).getName(), codebook); - final SqQvcFile cacheFile = new SqQvcFile(header, codebook); - - try (final FileOutputStream fos = new FileOutputStream(fileName, false); - final DataOutputStream dos = new DataOutputStream(fos)) { - - cacheFile.writeToStream(dos); - } catch (final IOException ex) { - throw new IOException("Failed to save SQ QVC file\n" + ex.getMessage()); - } - return fileName; + final String path = getCacheFilePathForSQ(trainFile, codebook.getCodebookSize()).getAbsolutePath(); + QvcFileWriter.writeSqCacheFile(path, trainFile, codebook); + return path; } @@ -147,21 +83,12 @@ public class QuantizationCacheManager { * @throws IOException when fails to save the cache file. */ public String saveCodebook(final String trainFile, final VQCodebook codebook) throws IOException { - final String fileName = getCacheFilePathForVQ(trainFile, - codebook.getCodebookSize(), - codebook.getVectorDims()).getAbsolutePath(); + final String path = getCacheFilePathForVQ(trainFile, + codebook.getCodebookSize(), + codebook.getVectorDims()).getAbsolutePath(); - final QvcHeaderV2 header = createHeaderForVQ(new File(trainFile).getName(), codebook); - final VqQvcFile cacheFile = new VqQvcFile(header, codebook); - - try (final FileOutputStream fos = new FileOutputStream(fileName, false); - final DataOutputStream dos = new DataOutputStream(fos)) { - - cacheFile.writeToStream(dos); - } catch (final IOException ex) { - throw new IOException("Failed to save VQ cache file\n" + ex.getMessage()); - } - return fileName; + QvcFileWriter.writeVqCacheFile(path, trainFile, codebook); + return path; } /** diff --git a/src/main/java/cz/it4i/qcmp/cache/QvcFileWriter.java b/src/main/java/cz/it4i/qcmp/cache/QvcFileWriter.java new file mode 100644 index 0000000000000000000000000000000000000000..a643f59ec1ac67836a6cec552cb94efbd16bd6dd --- /dev/null +++ b/src/main/java/cz/it4i/qcmp/cache/QvcFileWriter.java @@ -0,0 +1,111 @@ +package cz.it4i.qcmp.cache; + +import cz.it4i.qcmp.data.V3i; +import cz.it4i.qcmp.fileformat.QuantizationType; +import cz.it4i.qcmp.fileformat.QvcHeaderV2; +import cz.it4i.qcmp.fileformat.SqQvcFile; +import cz.it4i.qcmp.fileformat.VqQvcFile; +import cz.it4i.qcmp.quantization.scalar.SQCodebook; +import cz.it4i.qcmp.quantization.vector.VQCodebook; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class QvcFileWriter { + /** + * Create QVC file header for SqQvc file. + * + * @param trainFile Image file used for training. + * @param codebook Final SQ codebook. + * @return SQ cache file header. + */ + private static QvcHeaderV2 createQvcHeaderForSQ(final String trainFile, final SQCodebook codebook) { + final QvcHeaderV2 header = new QvcHeaderV2(); + header.setQuantizationType(QuantizationType.Scalar); + header.setCodebookSize(codebook.getCodebookSize()); + header.setTrainFileName(trainFile); + header.setVectorDims(new V3i(0)); + return header; + } + + /** + * Find the correct quantization type based on vector dimension. + * + * @param vectorDims Quantization vector dimensions. + * @return Correct QuantizationType. + */ + private static QuantizationType getQuantizationTypeFromVectorDimensions(final V3i vectorDims) { + if (vectorDims.getX() > 1) { + if (vectorDims.getY() == 1 && vectorDims.getZ() == 1) { + return QuantizationType.Vector1D; + } else if (vectorDims.getY() > 1 && vectorDims.getZ() == 1) { + return QuantizationType.Vector2D; + } else { + return QuantizationType.Vector3D; + } + } else if (vectorDims.getX() == 1 && vectorDims.getY() > 1 && vectorDims.getZ() == 1) { + return QuantizationType.Vector1D; + } + return QuantizationType.Invalid; + } + + /** + * Create QVC file header for VqQvc file. + * + * @param trainFile Image file used for training. + * @param codebook Final VQ codebook. + * @return VQ cache file header. + */ + private static QvcHeaderV2 createQvcHeaderForVq(final String trainFile, final VQCodebook codebook) { + final QvcHeaderV2 header = new QvcHeaderV2(); + header.setQuantizationType(getQuantizationTypeFromVectorDimensions(codebook.getVectorDims())); + header.setCodebookSize(codebook.getCodebookSize()); + header.setTrainFileName(trainFile); + header.setVectorDims(codebook.getVectorDims()); + return header; + } + + /** + * Save scalar quantization codebook as QVC file in file specified by path. + * + * @param path Cache file path. + * @param trainFile Image file used for training. + * @param codebook Scalar quantization codebook. + * @throws IOException when fails to write the cache file. + */ + public static void writeSqCacheFile(final String path, final String trainFile, final SQCodebook codebook) throws IOException { + final QvcHeaderV2 header = createQvcHeaderForSQ(new File(trainFile).getName(), codebook); + final SqQvcFile cacheFile = new SqQvcFile(header, codebook); + + try (final FileOutputStream fos = new FileOutputStream(path, false); + final DataOutputStream dos = new DataOutputStream(fos)) { + + cacheFile.writeToStream(dos); + } catch (final IOException ex) { + throw new IOException("Failed to save SQ QVC file\n" + ex.getMessage()); + } + } + + /** + * Save vector quantization codebook as QVC file in file specified by path. + * + * @param path Cache file path. + * @param trainFile Image file used for training. + * @param codebook Vector quantization codebook. + * @throws IOException when fails to save the cache file. + */ + public static void writeVqCacheFile(final String path, final String trainFile, final VQCodebook codebook) throws IOException { + final QvcHeaderV2 header = createQvcHeaderForVq(new File(trainFile).getName(), codebook); + final VqQvcFile cacheFile = new VqQvcFile(header, codebook); + + try (final FileOutputStream fos = new FileOutputStream(path, false); + final DataOutputStream dos = new DataOutputStream(fos)) { + + cacheFile.writeToStream(dos); + } catch (final IOException ex) { + throw new IOException("Failed to save VQ QVC file\n" + ex.getMessage()); + } + } +}