View Javadoc
1   package nom.tam.image.compression.tile.mask;
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 java.nio.ByteBuffer;
35  
36  import nom.tam.fits.compression.algorithm.api.ICompressorControl;
37  import nom.tam.image.tile.operation.buffer.TileBuffer;
38  
39  /**
40   * (<i>for internal use</i>) Base support for blank (<code>null</code>) in
41   * compressed images. In regular images specific values (such as
42   * {@link Double#NaN} or a specific integer value) may be used to indicate
43   * missing data. However, because of e.g. quantization or lossy compression,
44   * these specific values may not be recovered exactly when compressing /
45   * decompressing images. Hence, there is a need to demark <code>null</code>
46   * values differently in copmressed images. This class provides support for that
47   * purpose.
48   */
49  public class AbstractNullPixelMask {
50  
51      private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
52  
53      /** Byte value signifying invalid / null data */
54      protected static final byte NULL_INDICATOR = (byte) 1;
55  
56      private final TileBuffer tileBuffer;
57  
58      private final int tileIndex;
59  
60      private final long nullValue;
61  
62      private ByteBuffer mask;
63  
64      private final ICompressorControl compressorControl;
65  
66      /**
67       * Creates a new pixel mask got a given image tile and designated null
68       * value.
69       * 
70       * @param tileBuffer
71       *            the buffer containing the tile data
72       * @param tileIndex
73       *            the tile index
74       * @param nullValue
75       *            the integer value representing <code>null</code> or invalid
76       *            data
77       * @param compressorControl
78       *            The class managing the compression
79       * @throws IllegalStateException
80       *             if the compressorControl argument is <code>null</code>
81       */
82      protected AbstractNullPixelMask(TileBuffer tileBuffer, int tileIndex, long nullValue, ICompressorControl compressorControl) throws IllegalStateException {
83          this.tileBuffer = tileBuffer;
84          this.tileIndex = tileIndex;
85          this.nullValue = nullValue;
86          this.compressorControl = compressorControl;
87          if (this.compressorControl == null) {
88              throw new IllegalStateException("Compression algorithm for the null pixel mask not available");
89          }
90      }
91  
92      /**
93       * Returns a byte array containing the mask
94       * 
95       * @return the byte array containing the pixel mask for the tile.
96       * @deprecated (<i>for internal use</i>) Visibility may be reduced to
97       *             package level in the future.
98       */
99      public byte[] getMaskBytes() {
100         if (mask == null) {
101             return EMPTY_BYTE_ARRAY;
102         }
103         int size = mask.position();
104         byte[] result = new byte[size];
105         mask.rewind();
106         mask.get(result);
107         return result;
108     }
109 
110     /**
111      * Sets data for a new mask as a flattened buffer of data.
112      * 
113      * @param mask
114      *            the buffer containing the mask data in flattened format.
115      */
116     public void setMask(ByteBuffer mask) {
117         this.mask = mask;
118     }
119 
120     /**
121      * Returns the object that manages the compression, and which therefore
122      * handles the masking
123      * 
124      * @return the object that manages the compression.
125      */
126     protected ICompressorControl getCompressorControl() {
127         return compressorControl;
128     }
129 
130     /**
131      * Returns the mask data as a buffer in flattened format.
132      * 
133      * @return the buffer containing the mask data in flattened format.
134      */
135     protected ByteBuffer getMask() {
136         return mask;
137     }
138 
139     /**
140      * Returns the value that represents a <code>null</code> or an undefined
141      * data point.
142      * 
143      * @return the value that demarks an undefined datum.
144      */
145     protected long getNullValue() {
146         return nullValue;
147     }
148 
149     /**
150      * Returns the buffer that holds data for an image tile.
151      * 
152      * @return the buffer that holds data for a single image tile.
153      */
154     protected TileBuffer getTileBuffer() {
155         return tileBuffer;
156     }
157 
158     /**
159      * Return the tile index for the image tile that is processed.
160      * 
161      * @return the image tile index
162      */
163     protected int getTileIndex() {
164         return tileIndex;
165     }
166 
167     /**
168      * Creates an internal buffer for holding the mask data, for the specified
169      * number of points.
170      * 
171      * @param remaining
172      *            the number of points the mask should accomodate.
173      * @return the internal buffer that may store the mask data for the
174      *         specified number of data points.
175      */
176     protected ByteBuffer initializedMask(int remaining) {
177         if (mask == null) {
178             mask = ByteBuffer.allocate(remaining);
179         }
180         return mask;
181     }
182 }