All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nom.tam.image.StreamingTileImageData Maven / Gradle / Ivy

package nom.tam.image;

/*-
 * #%L
 * nom.tam.fits
 * %%
 * Copyright (C) 1996 - 2024 nom-tam-fits
 * %%
 * This is free and unencumbered software released into the public domain.
 * 
 * Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled
 * binary, for any purpose, commercial or non-commercial, and by any
 * means.
 * 
 * In jurisdictions that recognize copyright laws, the author or authors
 * of this software dedicate any and all copyright interest in the
 * software to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and
 * successors. We intend this dedication to be an overt act of
 * relinquishment in perpetuity of all present and future rights to this
 * software under copyright law.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * #L%
 */

import java.io.IOException;
import java.util.Arrays;

import nom.tam.fits.FitsException;
import nom.tam.fits.FitsUtil;
import nom.tam.fits.Header;
import nom.tam.fits.ImageData;
import nom.tam.util.ArrayDataOutput;
import nom.tam.util.ArrayFuncs;

/**
 * 

* Simple streaming image tile implementation. Useful for web applications that provide a cutout service. The idea is * that the ImageData object will be extracted from an overlapping HDU (without first reading so as not to fill up the * memory), and one of these objects are created for the output. *

* *
 *     Fits source = new Fits(myFile);
 *     ImageHDU imageHDU = source.getHDU(1);
 *
 *     // We must manually adjust the header for the cutout image as necessary
 *     Header tileHeader = ...
 *
 *     // Define the cutout region
 *     int[] tileStarts = new int[]{10, 10};
 *     int[] tileLengths = new int[]{45, 60};
 *     int[] tileSteps = new int[]{1, 1};
 *
 *     // Create the cutout
 *     StreamingTileImageData streamingTileImageData = new StreamingTileImageData(tileHeader, imageHDU.getTiler(),
 *         tileStarts, tileLengths, tileSteps);
 *
 *     // Write the cutout to the output
 *     Fits output = new Fits();
 *     output.addHDU(FitsFactory.hduFactory(tileHeader, streamingTileImageData));
 *
 *     // The cutout happens at write time!
 *     output.write(outputStream);
 * 
* * @since 1.18 */ public class StreamingTileImageData extends ImageData { private final int[] corners; private final int[] lengths; private final int[] steps; private final ImageTiler imageTiler; /** * Constructor for a tile image data object. * * @param header The header representing the desired cutout. It is the responsibility of the caller to * adjust the header appropriately. * @param tiler The tiler to slice pixels out with. * @param corners The corners to start tiling. * @param lengths The count of values to extract. * @param steps The number of jumps to make to the next read. Optional, defaults to 1 for each axis. * * @throws FitsException If the provided Header is unreadable */ public StreamingTileImageData(final Header header, final ImageTiler tiler, final int[] corners, final int[] lengths, int[] steps) throws FitsException { super(header); if (ArrayFuncs.isEmpty(corners) || ArrayFuncs.isEmpty(lengths)) { throw new IllegalArgumentException( "Cannot tile out with empty corners or lengths. Use ImageData if no " + "tiling is desired."); } if (ArrayFuncs.isEmpty(steps)) { this.steps = new int[corners.length]; Arrays.fill(this.steps, 1); } else if (Arrays.stream(steps).anyMatch(i -> i < 1)) { throw new IllegalArgumentException("Negative or zero step values not supported."); } else { this.steps = steps; } imageTiler = tiler; this.corners = corners; this.lengths = lengths; } /** * Returns the striding step sizes along the various image dimensions. * * @return an array containing the steps sizes along the dimensions */ public int[] getSteps() { // Steps is always initialized so no need to check for null here... return Arrays.copyOf(steps, steps.length); } @SuppressWarnings("deprecation") @Override public void write(ArrayDataOutput o) throws FitsException { try { final ImageTiler tiler = imageTiler; if (tiler == null || getTrueSize() == 0) { // Defer writing of unknowns to the parent. super.write(o); } else { tiler.getTile(o, corners, lengths, steps); FitsUtil.pad(o, getTrueSize()); } } catch (IOException ioException) { throw new FitsException(ioException.getMessage(), ioException); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy