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>) Preserves blank (<code>null</code>) values in
47   * compressed images. This class overwrites the pixels specified in the mask
48   * with null values. Where the null value can be defined separately.
49   * 
50   * @see nom.tam.image.compression.hdu.CompressedImageHDU
51   */
52  public class NullPixelMaskPreserver extends AbstractNullPixelMask {
53  
54      /**
55       * Creates a new instance for preserving the null values in a specific image
56       * tile when compressing the tile.
57       * 
58       * @param tileBuffer
59       *            the buffer containing the serialized tile data (still
60       *            uncompressed)
61       * @param tileIndex
62       *            the sequential tile index
63       * @param nullValue
64       *            the blank value used in integer type images (this is ignored
65       *            for floating-point images where NaN is used always)
66       * @param compressorControl
67       *            the class that performs the compresion of tiles, and which
68       *            will be used to compress the null pixel mask also.
69       */
70      public NullPixelMaskPreserver(TileBuffer tileBuffer, int tileIndex, long nullValue, ICompressorControl compressorControl) {
71          super(tileBuffer, tileIndex, nullValue, compressorControl);
72      }
73  
74      /**
75       * Creates a compressed mask to store along with the compressed tile image
76       * to indicate where the blanking values appear in in the original image.
77       */
78      public void preserveNull() {
79          if (getTileBuffer().getBaseType().is(ElementType.DOUBLE)) {
80              preserveNullDoubles();
81          } else if (getTileBuffer().getBaseType().is(ElementType.FLOAT)) {
82              preserveNullFloats();
83          } else if (getTileBuffer().getBaseType().is(ElementType.LONG)) {
84              preserveNullLongs();
85          } else if (getTileBuffer().getBaseType().is(ElementType.INT)) {
86              preserveNullInts();
87          } else if (getTileBuffer().getBaseType().is(ElementType.SHORT)) {
88              preserveNullShorts();
89          } else if (getTileBuffer().getBaseType().is(ElementType.BYTE)) {
90              preserveNullBytes();
91          }
92          if (getMask() != null) {
93              ByteBuffer compressed = ByteBuffer.allocate(getTileBuffer().getPixelSize());
94              if (!getCompressorControl().compress(getMask(), compressed, getCompressorControl().option())) {
95                  throw new IllegalStateException("could not compress the null pixel mask");
96              }
97              setMask(compressed);
98          }
99      }
100 
101     private void preserveNullBytes() {
102         ByteBuffer buffer = (ByteBuffer) getTileBuffer().getBuffer();
103         byte nullValue = (byte) getNullValue();
104         int size = buffer.remaining();
105         for (int index = 0; index < size; index++) {
106             if (nullValue == buffer.get(index)) {
107                 initializedMask(size).put(index, NULL_INDICATOR);
108             }
109         }
110     }
111 
112     private void preserveNullDoubles() {
113         DoubleBuffer buffer = (DoubleBuffer) getTileBuffer().getBuffer();
114         int size = getTileBuffer().getPixelSize();
115         for (int index = 0; index < size; index++) {
116             if (Double.isNaN(buffer.get(index))) {
117                 initializedMask(size).put(index, NULL_INDICATOR);
118             }
119         }
120     }
121 
122     private void preserveNullFloats() {
123         FloatBuffer buffer = (FloatBuffer) getTileBuffer().getBuffer();
124         int size = getTileBuffer().getPixelSize();
125         for (int index = 0; index < size; index++) {
126             if (Float.isNaN(buffer.get(index))) {
127                 initializedMask(size).put(index, NULL_INDICATOR);
128             }
129         }
130     }
131 
132     private void preserveNullInts() {
133         IntBuffer buffer = (IntBuffer) getTileBuffer().getBuffer();
134         int nullValue = (int) getNullValue();
135         int size = getTileBuffer().getPixelSize();
136         for (int index = 0; index < size; index++) {
137             if (nullValue == buffer.get(index)) {
138                 initializedMask(size).put(index, NULL_INDICATOR);
139             }
140         }
141     }
142 
143     private void preserveNullLongs() {
144         LongBuffer buffer = (LongBuffer) getTileBuffer().getBuffer();
145         long nullValue = getNullValue();
146         int size = getTileBuffer().getPixelSize();
147         for (int index = 0; index < size; index++) {
148             if (nullValue == buffer.get(index)) {
149                 initializedMask(size).put(index, NULL_INDICATOR);
150             }
151         }
152     }
153 
154     private void preserveNullShorts() {
155         ShortBuffer buffer = (ShortBuffer) getTileBuffer().getBuffer();
156         short nullValue = (short) getNullValue();
157         int size = getTileBuffer().getPixelSize();
158         for (int index = 0; index < size; index++) {
159             if (nullValue == buffer.get(index)) {
160                 initializedMask(size).put(index, NULL_INDICATOR);
161             }
162         }
163     }
164 
165 }