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 }