1 package nom.tam.fits; 2 3 import java.io.PrintStream; 4 import java.util.logging.Level; 5 import java.util.logging.Logger; 6 7 import nom.tam.fits.header.Standard; 8 import nom.tam.image.StandardImageTiler; 9 import nom.tam.util.ArrayFuncs; 10 11 /* 12 * #%L 13 * nom.tam FITS library 14 * %% 15 * Copyright (C) 2004 - 2024 nom-tam-fits 16 * %% 17 * This is free and unencumbered software released into the public domain. 18 * 19 * Anyone is free to copy, modify, publish, use, compile, sell, or 20 * distribute this software, either in source code form or as a compiled 21 * binary, for any purpose, commercial or non-commercial, and by any 22 * means. 23 * 24 * In jurisdictions that recognize copyright laws, the author or authors 25 * of this software dedicate any and all copyright interest in the 26 * software to the public domain. We make this dedication for the benefit 27 * of the public at large and to the detriment of our heirs and 28 * successors. We intend this dedication to be an overt act of 29 * relinquishment in perpetuity of all present and future rights to this 30 * software under copyright law. 31 * 32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 34 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 35 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 36 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 37 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 38 * OTHER DEALINGS IN THE SOFTWARE. 39 * #L% 40 */ 41 42 import static nom.tam.fits.header.Standard.BITPIX; 43 import static nom.tam.fits.header.Standard.GROUPS; 44 import static nom.tam.fits.header.Standard.NAXIS; 45 import static nom.tam.fits.header.Standard.NAXISn; 46 import static nom.tam.fits.header.Standard.SIMPLE; 47 import static nom.tam.fits.header.Standard.XTENSION; 48 import static nom.tam.util.LoggerHelper.getLogger; 49 50 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 51 52 /** 53 * Header/data unit for images. Image HDUs are suitable for storing monolithic regular numerical arrays in 1 to 255 54 * dimensions, such as a <code>double[]</code>, <code>float[][]</code>, or <code>short[][][]</code>. ((FITS supports up 55 * to 999 dimensions, but Java support maxes at at 255 -- however it's unlikely you'll find this to be a serious 56 * limitation.) 57 * 58 * @see ImageData 59 */ 60 @SuppressWarnings("deprecation") 61 public class ImageHDU extends BasicHDU<ImageData> { 62 63 private static final Logger LOG = getLogger(ImageHDU.class); 64 65 @Override 66 protected final String getCanonicalXtension() { 67 return Standard.XTENSION_IMAGE; 68 } 69 70 /** 71 * @deprecated (<i>for internal use</i>) Use {@link ImageData#from(Object)} instead. Will 72 * reduce visibility in the future 73 * 74 * @return Encapsulate an object as an ImageHDU. 75 * 76 * @param o object to encapsulate 77 * 78 * @throws FitsException <i>does not actually throw this exception</i> 79 * @throws IllegalArgumentException if the data is not a regular primitive numerical array suitable for an 80 * image. 81 */ 82 @Deprecated 83 public static ImageData encapsulate(Object o) throws IllegalArgumentException, FitsException { 84 return new ImageData(o); 85 } 86 87 /** 88 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 89 * 90 * @return is this object can be described as a FITS image. 91 * 92 * @param o The Object being tested. 93 */ 94 @SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "deprecated existing method, kept for compatibility") 95 @Deprecated 96 public static boolean isData(Object o) { 97 try { 98 ImageData.checkCompatible(o); 99 } catch (Exception e) { 100 return false; 101 } 102 return true; 103 } 104 105 /** 106 * Check that this HDU has a valid header for this type. 107 * 108 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 109 * 110 * @param hdr header to check 111 * 112 * @return <CODE>true</CODE> if this HDU has a valid header. 113 */ 114 @SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "deprecated existing method, kept for compatibility") 115 @Deprecated 116 public static boolean isHeader(Header hdr) { 117 boolean found = hdr.getBooleanValue(SIMPLE); 118 if (!found) { 119 String xtension = hdr.getStringValue(XTENSION); 120 xtension = xtension == null ? "" : xtension.trim(); 121 if (Standard.XTENSION_IMAGE.equals(xtension) || "IUEIMAGE".equals(xtension)) { 122 found = true; 123 } 124 } 125 if (!found) { 126 return false; 127 } 128 return !hdr.getBooleanValue(GROUPS); 129 } 130 131 /** 132 * Prepares a data object into which the actual data can be read from an input subsequently or at a later time. 133 * 134 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 135 * 136 * @param hdr The FITS header that describes the data 137 * 138 * @return A data object that support reading content from a stream. 139 * 140 * @throws FitsException if the data could not be prepared to prescriotion. 141 */ 142 @Deprecated 143 public static ImageData manufactureData(Header hdr) throws FitsException { 144 return new ImageData(hdr); 145 } 146 147 /** 148 * Prepares a data object into which the actual data can be read from an input subsequently or at a later time. 149 * 150 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 151 * 152 * @param d The FITS data content of this HDU 153 * 154 * @return A data object that support reading content from a stream. 155 * 156 * @throws FitsException if the data could not be prepared to prescriotion. 157 */ 158 @Deprecated 159 public static Header manufactureHeader(Data d) throws FitsException { 160 if (d == null) { 161 return null; 162 } 163 164 Header h = new Header(); 165 d.fillHeader(h); 166 167 return h; 168 } 169 170 /** 171 * Build an image HDU using the supplied data. 172 * 173 * @deprecated (<i>for internal use</i>) Its visibility should be reduced to package level in the future. 174 * 175 * @param h the header for the image. 176 * @param d the data used in the image. 177 */ 178 public ImageHDU(Header h, ImageData d) { 179 super(h, d); 180 } 181 182 /** 183 * Returns the class that can be used to divide this image into tiles that may be processed separately (and in 184 * parallel). 185 * 186 * @return image tiler for this image instance. 187 * 188 * @see ImageData#getTiler() 189 */ 190 public StandardImageTiler getTiler() { 191 return myData.getTiler(); 192 } 193 194 @Override 195 public void info(PrintStream stream) { 196 if (isHeader(myHeader)) { 197 stream.println(" Image"); 198 } else { 199 stream.println(" Image (bad header)"); 200 } 201 202 stream.println(" Header Information:"); 203 stream.println(" BITPIX=" + myHeader.getIntValue(BITPIX, -1)); 204 int naxis = myHeader.getIntValue(NAXIS, -1); 205 stream.println(" NAXIS=" + naxis); 206 for (int i = 1; i <= naxis; i++) { 207 stream.println(" NAXIS" + i + "=" + myHeader.getIntValue(NAXISn.n(i), -1)); 208 } 209 210 stream.println(" Data information:"); 211 try { 212 if (myData.getData() == null) { 213 stream.println(" No Data"); 214 } else { 215 stream.println(" " + ArrayFuncs.arrayDescription(myData.getData())); 216 } 217 } catch (Exception e) { 218 LOG.log(Level.SEVERE, "Unable to get image data", e); 219 stream.println(" Unable to get data"); 220 } 221 } 222 223 /** 224 * Returns the name of the physical unit in which images are represented. 225 * 226 * @return the standard name of the physical unit in which the image is expressed, e.g. <code>"Jy beam^{-1}"</code>. 227 */ 228 @Override 229 public String getBUnit() { 230 return super.getBUnit(); 231 } 232 233 /** 234 * Returns the integer value that signifies blank (missing or <code>null</code>) data in an integer image. 235 * 236 * @return the integer value used for identifying blank / missing data in integer images. 237 * 238 * @throws FitsException if the header does not specify a blanking value or if it is not appropriate for the type of 239 * imge (that is not an integer type image) 240 */ 241 @Override 242 public long getBlankValue() throws FitsException { 243 if (getBitpix().getHeaderValue() < 0) { 244 throw new FitsException("No integer blanking value in floating-point images."); 245 } 246 return super.getBlankValue(); 247 } 248 249 /** 250 * Returns the floating-point increment between adjacent integer values in the image. Strictly speaking, only 251 * integer-type images should define a quantization scaling, but there is no harm in having this value in 252 * floating-point images also -- which may be interpreted as a hint for quantization, perhaps. 253 * 254 * @return the floating-point quantum that corresponds to the increment of 1 in the integer data representation. 255 * 256 * @see #getBZero() 257 */ 258 @Override 259 public double getBScale() { 260 return super.getBScale(); 261 } 262 263 /** 264 * Returns the floating-point value that corresponds to an 0 integer value in the image. Strictly speaking, only 265 * integer-type images should define a quantization offset, but there is no harm in having this value in 266 * floating-point images also -- which may be interpreted as a hint for quantization, perhaps. 267 * 268 * @return the floating point value that correspond to the integer 0 in the image data. 269 * 270 * @see #getBScale() 271 */ 272 @Override 273 public double getBZero() { 274 return super.getBZero(); 275 } 276 277 }