1 package nom.tam.image.tile.operation; 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.Buffer; 35 import java.util.concurrent.ExecutorService; 36 import java.util.concurrent.Future; 37 38 import nom.tam.image.tile.operation.buffer.TileBuffer; 39 import nom.tam.image.tile.operation.buffer.TileBufferFactory; 40 import nom.tam.util.type.ElementType; 41 42 /** 43 * (<i>for internal use</i>) A base implementation of parallel processing of tiles. Each instance handles the processing 44 * of a single 2D image tile, which is submitted to a thread pool for parallel processing of multiple tiles 45 * simultaneously. 46 */ 47 public abstract class AbstractTileOperation implements Runnable, ITileOperation { 48 49 private final ITiledImageOperation tiledImageOperation; 50 51 private Future<?> future; 52 53 private TileBuffer tileBuffer; 54 55 private final int tileIndex; 56 57 private final TileArea area; 58 59 /** 60 * Creates a parallel tile processing operation for a specific 2D image tile. 61 * 62 * @param operation the operation that is to be performed on the tile 63 * @param tileIndex the sequential tile index 64 * @param area the location and size of tile in the full image. 65 */ 66 public AbstractTileOperation(ITiledImageOperation operation, int tileIndex, TileArea area) { 67 tiledImageOperation = operation; 68 this.tileIndex = tileIndex; 69 this.area = area; 70 } 71 72 /** 73 * Performs the operation on the selected tile, by submitting it to a thread pool for parallel processing. 74 * 75 * @param threadPool The thread pool in which the operation is to be processed. 76 * 77 * @see #waitForResult() 78 */ 79 public void execute(ExecutorService threadPool) { 80 future = threadPool.submit(this); 81 } 82 83 /** 84 * Returns the location and size of the 2D image tile inside the entire image 85 * 86 * @return the location and size of the tile in the full image. 87 */ 88 public TileArea getArea() { 89 return area; 90 } 91 92 /** 93 * Returns the pixel count inside the tile that this operation is assigned to process. 94 * 95 * @return the number of pixels in this tile. 96 */ 97 public int getPixelSize() { 98 return tileBuffer.getPixelSize(); 99 } 100 101 /** 102 * Returns the sequential index of the tile that this operations is assigned to process. 103 * 104 * @return the sequential index of the tile 105 */ 106 public int getTileIndex() { 107 return tileIndex; 108 } 109 110 /** 111 * Sets the buffer that describes the whole image and let the tile create a slice of it from the position where the 112 * tile starts in the whole image. Attention this method is not thread-safe because it changes the position of the 113 * buffer parameter. 114 * 115 * @param buffer the buffer that describes the whole image. 116 */ 117 public void setWholeImageBuffer(Buffer buffer) { 118 tileBuffer.setData(buffer); 119 } 120 121 /** 122 * Wait for the result of the tile processing. 123 * 124 * @see #execute(ExecutorService) 125 */ 126 @Override 127 public void waitForResult() { 128 try { 129 future.get(); 130 } catch (Exception e) { 131 throw new IllegalStateException("could not process tile", e); 132 } 133 } 134 135 /** 136 * Returns the FITS element type of the image to be processed. 137 * 138 * @return the FITS element type of the underlying image 139 */ 140 protected ElementType<Buffer> getBaseType() { 141 return tiledImageOperation.getBaseType(); 142 } 143 144 /** 145 * Returns the parallel tile operation whose tile index is one less than ours. 146 * 147 * @return the parallel tile operation for the tile prior to ours. 148 */ 149 protected ITileOperation getPreviousTileOperation() { 150 return tiledImageOperation.getTileOperation(getTileIndex() - 1); 151 } 152 153 /** 154 * Returns the buffer that is to be used for storing or retrieving the serialized tile image. 155 * 156 * @return the linear buffer for the tile image. 157 * 158 * @see #setTileBuffer(TileBuffer) 159 */ 160 protected TileBuffer getTileBuffer() { 161 return tileBuffer; 162 } 163 164 /** 165 * Returns the operation that is assigned to be performed on the image tile. 166 * 167 * @return the operation to be performed on the associated image tile 168 */ 169 protected ITiledImageOperation getTiledImageOperation() { 170 return tiledImageOperation; 171 } 172 173 @SuppressWarnings("deprecation") 174 @Override 175 public ITileOperation setDimensions(int dataOffset, int width, int height) { 176 setTileBuffer(TileBufferFactory.createTileBuffer(getBaseType(), // 177 dataOffset, // 178 tiledImageOperation.getImageWidth(), // 179 width, height)); 180 area.size(width, height); 181 return this; 182 } 183 184 /** 185 * Sets the buffer to be used for storing or retrieving the serialized tile image. 186 * 187 * @param tileBuffer the linear buffer for the tile image. 188 * 189 * @see #getTileBuffer() 190 */ 191 protected void setTileBuffer(TileBuffer tileBuffer) { 192 this.tileBuffer = tileBuffer; 193 } 194 }