1 package nom.tam.fits.compression.provider.param.quant;
2
3 import nom.tam.fits.Header;
4
5 /*
6 * #%L
7 * nom.tam FITS library
8 * %%
9 * Copyright (C) 1996 - 2024 nom-tam-fits
10 * %%
11 * This is free and unencumbered software released into the public domain.
12 *
13 * Anyone is free to copy, modify, publish, use, compile, sell, or
14 * distribute this software, either in source code form or as a compiled
15 * binary, for any purpose, commercial or non-commercial, and by any
16 * means.
17 *
18 * In jurisdictions that recognize copyright laws, the author or authors
19 * of this software dedicate any and all copyright interest in the
20 * software to the public domain. We make this dedication for the benefit
21 * of the public at large and to the detriment of our heirs and
22 * successors. We intend this dedication to be an overt act of
23 * relinquishment in perpetuity of all present and future rights to this
24 * software under copyright law.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
30 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
31 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32 * OTHER DEALINGS IN THE SOFTWARE.
33 * #L%
34 */
35
36 import nom.tam.fits.HeaderCard;
37 import nom.tam.fits.HeaderCardException;
38 import nom.tam.fits.compression.algorithm.quant.QuantizeOption;
39 import nom.tam.fits.compression.provider.param.base.CompressHeaderParameter;
40 import nom.tam.fits.header.Compression;
41
42 /**
43 * (<i>for internal use</i>) The The random seed initialization parameter as recorded in the FITS header.
44 * <p>
45 * The storing of the random seed provides consistent dither implementations. Dithering adds a small amount of noise (at
46 * the level of the quantization level increments) to remove possible systematics biases of the quantization. Since the
47 * quantization (integer representation of floating-point values) is inherently lossy (noisy) the added dithering noise
48 * is generally inconsequential in terms of preseving information in the original image. As such, the image can be
49 * recovered close enough to the original, within the level of the quantization noise, without knowing the exact random
50 * sequence that was used to generate the dither.
51 * </p>
52 * <p>
53 * However, The FITS standard requires that when dithering is used in the compression the same tool (or library) should
54 * also undo the dithering exactly using the same sequence of random numbers as was used when compressing the image.
55 * Furthermore, the standard makes some explicit suggestions on how pseudo-random sequences should be generated, and
56 * offers a specific convention for an algorithm that may be used to provide consistent dithering across tools,
57 * platforms, and library implementations.
58 * </p>
59 * <p>
60 * For the dithering to be reversible, the FITS header should store the integer value, usually between 1 and 10000
61 * inclusive, under the <code>ZDITHER0</code> keyword to indicate the value (random sequence index) that was used for
62 * seeding the random number generator according to the described standard.
63 * </p>
64 * <p>
65 * The nom-tam FITS library implements the suggested convention for the random number generator, and this parameter
66 * deals with recording the corresponding random seed value via the <code>ZDITHER0</code> keyword in the compressed
67 * image headers; as well as retrieving this value to seed the random number generator when decompressing the image, in
68 * a way that is consistent with the FITS standard and recommended convention.
69 * </p>
70 *
71 * @author Attila Kovacs
72 */
73 final class ZDither0Parameter extends CompressHeaderParameter<QuantizeOption> {
74
75 /**
76 * Creates a new compression parameter that can be used to configure the quantization options when cmpressing /
77 * decompressing image tiles.
78 *
79 * @param quantizeOption The quantization option that will be configured using this particular parameter.
80 */
81 ZDither0Parameter(QuantizeOption quantizeOption) {
82 super(Compression.ZDITHER0.name(), quantizeOption);
83 }
84
85 @Override
86 public void getValueFromHeader(Header header) throws HeaderCardException {
87 if (getOption() == null) {
88 return;
89 }
90
91 HeaderCard card = header.getCard(Compression.ZDITHER0);
92 getOption().setSeed(card == null ? 1L : card.getValue(Long.class, 1L));
93 }
94
95 @Override
96 public void setValueInHeader(Header header) throws HeaderCardException {
97 if (getOption() == null) {
98 return;
99 }
100
101 header.addValue(Compression.ZDITHER0, (int) getOption().getSeed());
102 }
103
104 /**
105 * Seeds the random generator for the specific tile
106 *
107 * @param index the 0-based tile index.
108 *
109 * @throws NullPointerException if the parameter is no linked to a {@link QuantizeOption} instance (that is
110 * <code>null</code> was specified in the constructor).
111 */
112 void setTileIndex(int index) throws NullPointerException {
113 getOption().setTileIndex(index);
114 }
115
116 }