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  import java.nio.DoubleBuffer;
36  import java.nio.FloatBuffer;
37  import java.nio.IntBuffer;
38  import java.nio.LongBuffer;
39  import java.nio.ShortBuffer;
40  
41  import nom.tam.fits.compression.algorithm.api.ICompressorControl;
42  import nom.tam.image.tile.operation.buffer.TileBuffer;
43  import nom.tam.util.type.ElementType;
44  
45  /**
46   * (<i>for internal use</i>) Restores blank (<code>null</code>) values in
47   * deccompressed images.
48   * 
49   * @see nom.tam.image.compression.hdu.CompressedImageHDU
50   */
51  public class NullPixelMaskRestorer extends AbstractNullPixelMask {
52  
53      /**
54       * Creates a new instance for restoring the null values to a specific image
55       * tile when decompressing the tile.
56       * 
57       * @param tileBuffer
58       *            the buffer containing the serialized tile data (still
59       *            uncompressed)
60       * @param tileIndex
61       *            the sequential tile index
62       * @param nullValue
63       *            the blank value used in integer type images (this is ignored
64       *            for floating-point images where NaN is used always)
65       * @param compressorControl
66       *            the class that performs the decompresion of tiles, and which
67       *            will be used to decompress the null pixel mask also.
68       */
69      public NullPixelMaskRestorer(TileBuffer tileBuffer, int tileIndex, long nullValue, ICompressorControl compressorControl) {
70          super(tileBuffer, tileIndex, nullValue, compressorControl);
71      }
72  
73      /**
74       * Restores the original blanking values in the decompressed image based on
75       * the null pixel mask that was stored along with the compressed data.
76       */
77      public void restoreNulls() {
78          // if the mask is not present the tile contains no null pixels.
79          if (getMask() != null) {
80              ByteBuffer decompressed = ByteBuffer.allocate(getTileBuffer().getPixelSize());
81              getCompressorControl().decompress(getMask(), decompressed, getCompressorControl().option());
82              setMask(decompressed);
83              if (getTileBuffer().getBaseType().is(ElementType.DOUBLE)) {
84                  restoreNullDoubles();
85              } else if (getTileBuffer().getBaseType().is(ElementType.FLOAT)) {
86                  restoreNullFloats();
87              } else if (getTileBuffer().getBaseType().is(ElementType.LONG)) {
88                  restoreNullLongs();
89              } else if (getTileBuffer().getBaseType().is(ElementType.INT)) {
90                  restoreNullInts();
91              } else if (getTileBuffer().getBaseType().is(ElementType.SHORT)) {
92                  restoreNullShorts();
93              } else if (getTileBuffer().getBaseType().is(ElementType.BYTE)) {
94                  restoreNullBytes();
95              }
96          }
97      }
98  
99      private void restoreNullBytes() {
100         ByteBuffer buffer = (ByteBuffer) getTileBuffer().getBuffer();
101         ByteBuffer nullMask = initializedMask(buffer.remaining());
102         byte nullValue = (byte) getNullValue();
103         for (int index = 0; index < nullMask.capacity(); index++) {
104             if (nullMask.get(index) == NULL_INDICATOR) {
105                 buffer.put(index, nullValue);
106             }
107         }
108     }
109 
110     private void restoreNullDoubles() {
111         DoubleBuffer buffer = (DoubleBuffer) getTileBuffer().getBuffer();
112         ByteBuffer nullMask = initializedMask(buffer.remaining());
113         for (int index = 0; index < nullMask.capacity(); index++) {
114             if (nullMask.get(index) == NULL_INDICATOR) {
115                 buffer.put(index, Double.NaN);
116             }
117         }
118     }
119 
120     private void restoreNullFloats() {
121         FloatBuffer buffer = (FloatBuffer) getTileBuffer().getBuffer();
122         ByteBuffer nullMask = initializedMask(buffer.remaining());
123         for (int index = 0; index < nullMask.capacity(); index++) {
124             if (nullMask.get(index) == NULL_INDICATOR) {
125                 buffer.put(index, Float.NaN);
126             }
127         }
128     }
129 
130     private void restoreNullInts() {
131         IntBuffer buffer = (IntBuffer) getTileBuffer().getBuffer();
132         ByteBuffer nullMask = initializedMask(buffer.remaining());
133         int nullValue = (int) getNullValue();
134         for (int index = 0; index < nullMask.capacity(); index++) {
135             if (nullMask.get(index) == NULL_INDICATOR) {
136                 buffer.put(index, nullValue);
137             }
138         }
139     }
140 
141     private void restoreNullLongs() {
142         LongBuffer buffer = (LongBuffer) getTileBuffer().getBuffer();
143         ByteBuffer nullMask = initializedMask(buffer.remaining());
144         long nullValue = getNullValue();
145         for (int index = 0; index < nullMask.capacity(); index++) {
146             if (nullMask.get(index) == NULL_INDICATOR) {
147                 buffer.put(index, nullValue);
148             }
149         }
150     }
151 
152     private void restoreNullShorts() {
153         ShortBuffer buffer = (ShortBuffer) getTileBuffer().getBuffer();
154         ByteBuffer nullMask = initializedMask(buffer.remaining());
155         short nullValue = (short) getNullValue();
156         for (int index = 0; index < nullMask.capacity(); index++) {
157             if (nullMask.get(index) == NULL_INDICATOR) {
158                 buffer.put(index, nullValue);
159             }
160         }
161     }
162 }