1 package nom.tam.fits.compression.algorithm.rice;
2
3 /*
4 * #%L
5 * nom.tam FITS library
6 * %%
7 * Copyright (C) 1996 - 2024 nom-tam-fits
8 * %%
9 * This is free and unencumbered software released into the public domain.
10 *
11 * Anyone is free to copy, modify, publish, use, compile, sell, or
12 * distribute this software, either in source code form or as a compiled
13 * binary, for any purpose, commercial or non-commercial, and by any
14 * means.
15 *
16 * In jurisdictions that recognize copyright laws, the author or authors
17 * of this software dedicate any and all copyright interest in the
18 * software to the public domain. We make this dedication for the benefit
19 * of the public at large and to the detriment of our heirs and
20 * successors. We intend this dedication to be an overt act of
21 * relinquishment in perpetuity of all present and future rights to this
22 * software under copyright law.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 * OTHER DEALINGS IN THE SOFTWARE.
31 * #L%
32 */
33
34 import nom.tam.fits.compression.algorithm.api.ICompressOption;
35 import nom.tam.fits.compression.provider.param.api.ICompressParameters;
36 import nom.tam.fits.compression.provider.param.rice.RiceCompressParameters;
37 import nom.tam.util.type.ElementType;
38
39 /**
40 * Options to the Rice compression algorithm. When compressing tables and images using the Rice algorithm, users can
41 * control how exactly the compression is perfomed. When reading compressed FITS files, these options will be set
42 * automatically based on the header values recorded in the compressed HDU.
43 *
44 * @see nom.tam.image.compression.hdu.CompressedImageHDU#setCompressAlgorithm(String)
45 * @see nom.tam.image.compression.hdu.CompressedImageHDU#getCompressOption(Class)
46 */
47 public class RiceCompressOption implements ICompressOption {
48
49 /** the default block size to use in bytes */
50 public static final int DEFAULT_RICE_BLOCKSIZE = 32;
51
52 /** the default BYTEPIX value */
53 public static final int DEFAULT_RICE_BYTEPIX = ElementType.INT.size();
54
55 /** Set of valid BYTEPIX values */
56 private static final int[] VALID_BYTEPIX = {1, 2, 4, 8};
57
58 /** Set of valid BLOCKSIZE values */
59 private static final int[] VALID_BLOCKSIZE = {16, 32};
60
61 /** The parameters that represent settings for this option in the FITS headers and/or compressed data columns */
62 private RiceCompressParameters parameters;
63
64 /** Shared configuration across copies */
65 private final Config config;
66
67 /**
68 * Creates a new set of options for Rice compression.
69 */
70 public RiceCompressOption() {
71 config = new Config();
72 parameters = new RiceCompressParameters(this);
73 }
74
75 @Override
76 public RiceCompressOption copy() {
77 try {
78 RiceCompressOption copy = (RiceCompressOption) clone();
79 copy.parameters = parameters.copy(copy);
80 return copy;
81 } catch (CloneNotSupportedException e) {
82 throw new IllegalStateException("option could not be cloned", e);
83 }
84 }
85
86 /**
87 * Returns the currently set block size.
88 *
89 * @return the block size in bytes.
90 *
91 * @see #setBlockSize(int)
92 */
93 public final int getBlockSize() {
94 return config.blockSize;
95 }
96
97 /**
98 * REturns the currently set BYTEPIX value
99 *
100 * @return the BYTEPIX value.
101 *
102 * @see #setBytePix(int)
103 */
104 public final int getBytePix() {
105 return config.bytePix;
106 }
107
108 @Override
109 public RiceCompressParameters getCompressionParameters() {
110 return parameters;
111 }
112
113 @Override
114 public boolean isLossyCompression() {
115 return false;
116 }
117
118 /**
119 * Sets a new block size to use
120 *
121 * @param value the new block size in bytes
122 *
123 * @return itself
124 *
125 * @throws IllegalArgumentException if the value is not 16 or 32.
126 *
127 * @see #getBlockSize()
128 */
129 public RiceCompressOption setBlockSize(int value) throws IllegalArgumentException {
130 for (int i : VALID_BLOCKSIZE) {
131 if (value == i) {
132 config.blockSize = value;
133 return this;
134 }
135 }
136 throw new IllegalArgumentException("Invalid BYTEPIX value: " + value + " (must be 16 or 32)");
137 }
138
139 /**
140 * Sets a new BYTEPIX value to use.
141 *
142 * @param value the new BYTEPIX value. It is currently not checked for validity, so use
143 * carefully.
144 *
145 * @return itself
146 *
147 * @throws IllegalArgumentException if the value is not 1, 2, 4, or 8.
148 *
149 * @see #getBytePix()
150 */
151 public RiceCompressOption setBytePix(int value) throws IllegalArgumentException {
152 for (int i : VALID_BYTEPIX) {
153 if (value == i) {
154 config.bytePix = value;
155 return this;
156 }
157 }
158 throw new IllegalArgumentException("Invalid BYTEPIX value: " + value + " (must be 1, 2, 4, or 8)");
159 }
160
161 @Override
162 public void setParameters(ICompressParameters parameters) {
163 if (!(parameters instanceof RiceCompressParameters)) {
164 throw new IllegalArgumentException("Wrong type of parameters: " + parameters.getClass().getName());
165 }
166 this.parameters = (RiceCompressParameters) parameters.copy(this);
167 }
168
169 @Override
170 public RiceCompressOption setTileHeight(int value) {
171 return this;
172 }
173
174 @Override
175 public RiceCompressOption setTileWidth(int value) {
176 return this;
177 }
178
179 @Override
180 public <T> T unwrap(Class<T> clazz) {
181 if (clazz.isAssignableFrom(this.getClass())) {
182 return clazz.cast(this);
183 }
184 return null;
185 }
186
187 /**
188 * Stores configuration in a way that can be shared and modified across enclosing option copies.
189 *
190 * @author Attila Kovacs
191 *
192 * @since 1.18
193 */
194 private static final class Config {
195 private int bytePix = DEFAULT_RICE_BYTEPIX;
196
197 private int blockSize = DEFAULT_RICE_BLOCKSIZE;
198 }
199 }