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 /** 51 * Header/data unit for images. Image HDUs are suitable for storing monolithic regular numerical arrays in 1 to 255 52 * dimensions, such as a <code>double[]</code>, <code>float[][]</code>, or <code>short[][][]</code>. ((FITS supports up 53 * to 999 dimensions, but Java support maxes at at 255 -- however it's unlikely you'll find this to be a serious 54 * limitation.) 55 * 56 * @see ImageData 57 */ 58 @SuppressWarnings("deprecation") 59 public class ImageHDU extends BasicHDU<ImageData> { 60 61 private static final Logger LOG = getLogger(ImageHDU.class); 62 63 @Override 64 protected final String getCanonicalXtension() { 65 return Standard.XTENSION_IMAGE; 66 } 67 68 /** 69 * @deprecated (<i>for internal use</i>) Use {@link ImageData#from(Object)} instead. Will 70 * reduce visibility in the future 71 * 72 * @return Encapsulate an object as an ImageHDU. 73 * 74 * @param o object to encapsulate 75 * 76 * @throws FitsException <i>does not actually throw this exception</i> 77 * @throws IllegalArgumentException if the data is not a regular primitive numerical array suitable for an 78 * image. 79 */ 80 @Deprecated 81 public static ImageData encapsulate(Object o) throws IllegalArgumentException, FitsException { 82 return new ImageData(o); 83 } 84 85 /** 86 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 87 * 88 * @return is this object can be described as a FITS image. 89 * 90 * @param o The Object being tested. 91 */ 92 @Deprecated 93 public static boolean isData(Object o) { 94 try { 95 ImageData.checkCompatible(o); 96 } catch (Exception e) { 97 return false; 98 } 99 return true; 100 } 101 102 /** 103 * Check that this HDU has a valid header for this type. 104 * 105 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 106 * 107 * @param hdr header to check 108 * 109 * @return <CODE>true</CODE> if this HDU has a valid header. 110 */ 111 @Deprecated 112 public static boolean isHeader(Header hdr) { 113 boolean found = hdr.getBooleanValue(SIMPLE); 114 if (!found) { 115 String xtension = hdr.getStringValue(XTENSION); 116 xtension = xtension == null ? "" : xtension.trim(); 117 if (Standard.XTENSION_IMAGE.equals(xtension) || "IUEIMAGE".equals(xtension)) { 118 found = true; 119 } 120 } 121 if (!found) { 122 return false; 123 } 124 return !hdr.getBooleanValue(GROUPS); 125 } 126 127 /** 128 * Prepares a data object into which the actual data can be read from an input subsequently or at a later time. 129 * 130 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 131 * 132 * @param hdr The FITS header that describes the data 133 * 134 * @return A data object that support reading content from a stream. 135 * 136 * @throws FitsException if the data could not be prepared to prescriotion. 137 */ 138 @Deprecated 139 public static ImageData manufactureData(Header hdr) throws FitsException { 140 return new ImageData(hdr); 141 } 142 143 /** 144 * Prepares a data object into which the actual data can be read from an input subsequently or at a later time. 145 * 146 * @deprecated (<i>for internal use</i>) Will reduce visibility in the future 147 * 148 * @param d The FITS data content of this HDU 149 * 150 * @return A data object that support reading content from a stream. 151 * 152 * @throws FitsException if the data could not be prepared to prescriotion. 153 */ 154 @Deprecated 155 public static Header manufactureHeader(Data d) throws FitsException { 156 if (d == null) { 157 return null; 158 } 159 160 Header h = new Header(); 161 d.fillHeader(h); 162 163 return h; 164 } 165 166 /** 167 * Build an image HDU using the supplied data. 168 * 169 * @deprecated (<i>for internal use</i>) Its visibility should be reduced to package level in the future. 170 * 171 * @param h the header for the image. 172 * @param d the data used in the image. 173 */ 174 public ImageHDU(Header h, ImageData d) { 175 super(h, d); 176 } 177 178 /** 179 * Returns the class that can be used to divide this image into tiles that may be processed separately (and in 180 * parallel). 181 * 182 * @return image tiler for this image instance. 183 * 184 * @see ImageData#getTiler() 185 */ 186 public StandardImageTiler getTiler() { 187 return myData.getTiler(); 188 } 189 190 @Override 191 public void info(PrintStream stream) { 192 if (isHeader(myHeader)) { 193 stream.println(" Image"); 194 } else { 195 stream.println(" Image (bad header)"); 196 } 197 198 stream.println(" Header Information:"); 199 stream.println(" BITPIX=" + myHeader.getIntValue(BITPIX, -1)); 200 int naxis = myHeader.getIntValue(NAXIS, -1); 201 stream.println(" NAXIS=" + naxis); 202 for (int i = 1; i <= naxis; i++) { 203 stream.println(" NAXIS" + i + "=" + myHeader.getIntValue(NAXISn.n(i), -1)); 204 } 205 206 stream.println(" Data information:"); 207 try { 208 if (myData.getData() == null) { 209 stream.println(" No Data"); 210 } else { 211 stream.println(" " + ArrayFuncs.arrayDescription(myData.getData())); 212 } 213 } catch (Exception e) { 214 LOG.log(Level.SEVERE, "Unable to get image data", e); 215 stream.println(" Unable to get data"); 216 } 217 } 218 219 /** 220 * Returns the name of the physical unit in which images are represented. 221 * 222 * @return the standard name of the physical unit in which the image is expressed, e.g. <code>"Jy beam^{-1}"</code>. 223 */ 224 @Override 225 public String getBUnit() { 226 return super.getBUnit(); 227 } 228 229 /** 230 * Returns the integer value that signifies blank (missing or <code>null</code>) data in an integer image. 231 * 232 * @return the integer value used for identifying blank / missing data in integer images. 233 * 234 * @throws FitsException if the header does not specify a blanking value or if it is not appropriate for the type of 235 * imge (that is not an integer type image) 236 */ 237 @Override 238 public long getBlankValue() throws FitsException { 239 if (getBitpix().getHeaderValue() < 0) { 240 throw new FitsException("No integer blanking value in floating-point images."); 241 } 242 return super.getBlankValue(); 243 } 244 245 /** 246 * Returns the floating-point increment between adjacent integer values in the image. Strictly speaking, only 247 * integer-type images should define a quantization scaling, but there is no harm in having this value in 248 * floating-point images also -- which may be interpreted as a hint for quantization, perhaps. 249 * 250 * @return the floating-point quantum that corresponds to the increment of 1 in the integer data representation. 251 * 252 * @see #getBZero() 253 */ 254 @Override 255 public double getBScale() { 256 return super.getBScale(); 257 } 258 259 /** 260 * Returns the floating-point value that corresponds to an 0 integer value in the image. Strictly speaking, only 261 * integer-type images should define a quantization offset, but there is no harm in having this value in 262 * floating-point images also -- which may be interpreted as a hint for quantization, perhaps. 263 * 264 * @return the floating point value that correspond to the integer 0 in the image data. 265 * 266 * @see #getBScale() 267 */ 268 @Override 269 public double getBZero() { 270 return super.getBZero(); 271 } 272 273 }