View Javadoc
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 }