/src/gdal/gcore/gdaldefaultasync.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: GDAL Core |
4 | | * Purpose: Implementation of GDALDefaultAsyncReader and the |
5 | | * GDALAsyncReader base class. |
6 | | * Author: Frank Warmerdam, warmerdam@pobox.com |
7 | | * |
8 | | ****************************************************************************** |
9 | | * Copyright (c) 2010, Frank Warmerdam |
10 | | * |
11 | | * SPDX-License-Identifier: MIT |
12 | | ****************************************************************************/ |
13 | | |
14 | | #include "cpl_port.h" |
15 | | #include "gdal_priv.h" |
16 | | |
17 | | #include <cstring> |
18 | | |
19 | | #include "cpl_conv.h" |
20 | | #include "cpl_error.h" |
21 | | #include "cpl_string.h" |
22 | | #include "gdal.h" |
23 | | |
24 | | /************************************************************************/ |
25 | | /* ==================================================================== */ |
26 | | /* GDALAsyncReader */ |
27 | | /* ==================================================================== */ |
28 | | /************************************************************************/ |
29 | | |
30 | | /************************************************************************/ |
31 | | /* GDALAsyncReader() */ |
32 | | /************************************************************************/ |
33 | | |
34 | | GDALAsyncReader::GDALAsyncReader() |
35 | 0 | : poDS(nullptr), nXOff(0), nYOff(0), nXSize(0), nYSize(0), pBuf(nullptr), |
36 | 0 | nBufXSize(0), nBufYSize(0), eBufType(GDT_Unknown), nBandCount(0), |
37 | 0 | panBandMap(nullptr), nPixelSpace(0), nLineSpace(0), nBandSpace(0) |
38 | 0 | { |
39 | 0 | } |
40 | | |
41 | | /************************************************************************/ |
42 | | /* ~GDALAsyncReader() */ |
43 | | /************************************************************************/ |
44 | 0 | GDALAsyncReader::~GDALAsyncReader() = default; |
45 | | |
46 | | /************************************************************************/ |
47 | | /* GetNextUpdatedRegion() */ |
48 | | /************************************************************************/ |
49 | | |
50 | | /** |
51 | | * \fn GDALAsyncStatusType GDALAsyncReader::GetNextUpdatedRegion( double |
52 | | * dfTimeout, int* pnBufXOff, int* pnBufYOff, int* pnBufXSize, int* pnBufYSize) |
53 | | * = 0; |
54 | | * |
55 | | * \brief Get async IO update |
56 | | * |
57 | | * Provide an opportunity for an asynchronous IO request to update the |
58 | | * image buffer and return an indication of the area of the buffer that |
59 | | * has been updated. |
60 | | * |
61 | | * The dfTimeout parameter can be used to wait for additional data to |
62 | | * become available. The timeout does not limit the amount |
63 | | * of time this method may spend actually processing available data. |
64 | | * |
65 | | * The following return status are possible. |
66 | | * - GARIO_PENDING: No imagery was altered in the buffer, but there is still |
67 | | * activity pending, and the application should continue to call |
68 | | * GetNextUpdatedRegion() as time permits. |
69 | | * - GARIO_UPDATE: Some of the imagery has been updated, but there is still |
70 | | * activity pending. |
71 | | * - GARIO_ERROR: Something has gone wrong. The asynchronous request should |
72 | | * be ended. |
73 | | * - GARIO_COMPLETE: An update has occurred and there is no more pending work |
74 | | * on this request. The request should be ended and the buffer used. |
75 | | * |
76 | | * @param dfTimeout the number of seconds to wait for additional updates. Use |
77 | | * -1 to wait indefinitely, or zero to not wait at all if there is no data |
78 | | * available. |
79 | | * @param pnBufXOff location to return the X offset of the area of the |
80 | | * request buffer that has been updated. |
81 | | * @param pnBufYOff location to return the Y offset of the area of the |
82 | | * request buffer that has been updated. |
83 | | * @param pnBufXSize location to return the X size of the area of the |
84 | | * request buffer that has been updated. |
85 | | * @param pnBufYSize location to return the Y size of the area of the |
86 | | * request buffer that has been updated. |
87 | | * |
88 | | * @return GARIO_ status, details described above. |
89 | | */ |
90 | | |
91 | | /************************************************************************/ |
92 | | /* GDALARGetNextUpdatedRegion() */ |
93 | | /************************************************************************/ |
94 | | |
95 | | /** |
96 | | * \brief Get async IO update |
97 | | * |
98 | | * Provide an opportunity for an asynchronous IO request to update the |
99 | | * image buffer and return an indication of the area of the buffer that |
100 | | * has been updated. |
101 | | * |
102 | | * The dfTimeout parameter can be used to wait for additional data to |
103 | | * become available. The timeout does not limit the amount |
104 | | * of time this method may spend actually processing available data. |
105 | | * |
106 | | * The following return status are possible. |
107 | | * - GARIO_PENDING: No imagery was altered in the buffer, but there is still |
108 | | * activity pending, and the application should continue to call |
109 | | * GetNextUpdatedRegion() as time permits. |
110 | | * - GARIO_UPDATE: Some of the imagery has been updated, but there is still |
111 | | * activity pending. |
112 | | * - GARIO_ERROR: Something has gone wrong. The asynchronous request should |
113 | | * be ended. |
114 | | * - GARIO_COMPLETE: An update has occurred and there is no more pending work |
115 | | * on this request. The request should be ended and the buffer used. |
116 | | * |
117 | | * This is the same as GDALAsyncReader::GetNextUpdatedRegion() |
118 | | * |
119 | | * @param hARIO handle to the async reader. |
120 | | * @param dfTimeout the number of seconds to wait for additional updates. Use |
121 | | * -1 to wait indefinitely, or zero to not wait at all if there is no data |
122 | | * available. |
123 | | * @param pnBufXOff location to return the X offset of the area of the |
124 | | * request buffer that has been updated. |
125 | | * @param pnBufYOff location to return the Y offset of the area of the |
126 | | * request buffer that has been updated. |
127 | | * @param pnBufXSize location to return the X size of the area of the |
128 | | * request buffer that has been updated. |
129 | | * @param pnBufYSize location to return the Y size of the area of the |
130 | | * request buffer that has been updated. |
131 | | * |
132 | | * @return GARIO_ status, details described above. |
133 | | */ |
134 | | |
135 | | GDALAsyncStatusType CPL_STDCALL GDALARGetNextUpdatedRegion( |
136 | | GDALAsyncReaderH hARIO, double dfTimeout, int *pnBufXOff, int *pnBufYOff, |
137 | | int *pnBufXSize, int *pnBufYSize) |
138 | 0 | { |
139 | 0 | VALIDATE_POINTER1(hARIO, "GDALARGetNextUpdatedRegion", GARIO_ERROR); |
140 | 0 | return static_cast<GDALAsyncReader *>(hARIO)->GetNextUpdatedRegion( |
141 | 0 | dfTimeout, pnBufXOff, pnBufYOff, pnBufXSize, pnBufYSize); |
142 | 0 | } |
143 | | |
144 | | /************************************************************************/ |
145 | | /* LockBuffer() */ |
146 | | /************************************************************************/ |
147 | | |
148 | | /** |
149 | | * \fn GDALAsyncReader::LockBuffer(double) |
150 | | * \brief Lock image buffer. |
151 | | * |
152 | | * Locks the image buffer passed into GDALDataset::BeginAsyncReader(). |
153 | | * This is useful to ensure the image buffer is not being modified while |
154 | | * it is being used by the application. UnlockBuffer() should be used |
155 | | * to release this lock when it is no longer needed. |
156 | | * |
157 | | * @param dfTimeout the time in seconds to wait attempting to lock the buffer. |
158 | | * -1.0 to wait indefinitely and 0 to not wait at all if it can't be |
159 | | * acquired immediately. Default is -1.0 (infinite wait). |
160 | | * |
161 | | * @return TRUE if successful, or FALSE on an error. |
162 | | */ |
163 | | |
164 | | /**/ |
165 | | /**/ |
166 | | |
167 | | int GDALAsyncReader::LockBuffer(double /* dfTimeout */) |
168 | 0 | { |
169 | 0 | return TRUE; |
170 | 0 | } |
171 | | |
172 | | /************************************************************************/ |
173 | | /* GDALARLockBuffer() */ |
174 | | /************************************************************************/ |
175 | | |
176 | | /** |
177 | | * \brief Lock image buffer. |
178 | | * |
179 | | * Locks the image buffer passed into GDALDataset::BeginAsyncReader(). |
180 | | * This is useful to ensure the image buffer is not being modified while |
181 | | * it is being used by the application. UnlockBuffer() should be used |
182 | | * to release this lock when it is no longer needed. |
183 | | * |
184 | | * This is the same as GDALAsyncReader::LockBuffer() |
185 | | * |
186 | | * @param hARIO handle to async reader. |
187 | | * @param dfTimeout the time in seconds to wait attempting to lock the buffer. |
188 | | * -1.0 to wait indefinitely and 0 to not wait at all if it can't be |
189 | | * acquired immediately. Default is -1.0 (infinite wait). |
190 | | * |
191 | | * @return TRUE if successful, or FALSE on an error. |
192 | | */ |
193 | | |
194 | | int CPL_STDCALL GDALARLockBuffer(GDALAsyncReaderH hARIO, double dfTimeout) |
195 | 0 | { |
196 | 0 | VALIDATE_POINTER1(hARIO, "GDALARLockBuffer", FALSE); |
197 | 0 | return static_cast<GDALAsyncReader *>(hARIO)->LockBuffer(dfTimeout); |
198 | 0 | } |
199 | | |
200 | | /************************************************************************/ |
201 | | /* UnlockBuffer() */ |
202 | | /************************************************************************/ |
203 | | |
204 | | /** |
205 | | * \brief Unlock image buffer. |
206 | | * |
207 | | * Releases a lock on the image buffer previously taken with LockBuffer(). |
208 | | */ |
209 | | |
210 | | void GDALAsyncReader::UnlockBuffer() |
211 | | |
212 | 0 | { |
213 | 0 | } |
214 | | |
215 | | /************************************************************************/ |
216 | | /* GDALARUnlockBuffer() */ |
217 | | /************************************************************************/ |
218 | | |
219 | | /** |
220 | | * \brief Unlock image buffer. |
221 | | * |
222 | | * Releases a lock on the image buffer previously taken with LockBuffer(). |
223 | | * |
224 | | * This is the same as GDALAsyncReader::UnlockBuffer() |
225 | | * |
226 | | * @param hARIO handle to async reader. |
227 | | */ |
228 | | |
229 | | void CPL_STDCALL GDALARUnlockBuffer(GDALAsyncReaderH hARIO) |
230 | 0 | { |
231 | 0 | VALIDATE_POINTER0(hARIO, "GDALARUnlockBuffer"); |
232 | 0 | static_cast<GDALAsyncReader *>(hARIO)->UnlockBuffer(); |
233 | 0 | } |
234 | | |
235 | | /************************************************************************/ |
236 | | /* ==================================================================== */ |
237 | | /* GDALDefaultAsyncReader */ |
238 | | /* ==================================================================== */ |
239 | | /************************************************************************/ |
240 | | |
241 | | class GDALDefaultAsyncReader : public GDALAsyncReader |
242 | | { |
243 | | private: |
244 | | char **papszOptions = nullptr; |
245 | | |
246 | | CPL_DISALLOW_COPY_ASSIGN(GDALDefaultAsyncReader) |
247 | | |
248 | | public: |
249 | | GDALDefaultAsyncReader(GDALDataset *poDS, int nXOff, int nYOff, int nXSize, |
250 | | int nYSize, void *pBuf, int nBufXSize, int nBufYSize, |
251 | | GDALDataType eBufType, int nBandCount, |
252 | | int *panBandMap, int nPixelSpace, int nLineSpace, |
253 | | int nBandSpace, CSLConstList papszOptions); |
254 | | ~GDALDefaultAsyncReader() override; |
255 | | |
256 | | GDALAsyncStatusType GetNextUpdatedRegion(double dfTimeout, int *pnBufXOff, |
257 | | int *pnBufYOff, int *pnBufXSize, |
258 | | int *pnBufYSize) override; |
259 | | }; |
260 | | |
261 | | /************************************************************************/ |
262 | | /* GDALGetDefaultAsyncReader() */ |
263 | | /************************************************************************/ |
264 | | |
265 | | GDALAsyncReader * |
266 | | GDALGetDefaultAsyncReader(GDALDataset *poDS, int nXOff, int nYOff, int nXSize, |
267 | | int nYSize, void *pBuf, int nBufXSize, int nBufYSize, |
268 | | GDALDataType eBufType, int nBandCount, |
269 | | int *panBandMap, int nPixelSpace, int nLineSpace, |
270 | | int nBandSpace, CSLConstList papszOptions) |
271 | | |
272 | 0 | { |
273 | 0 | return new GDALDefaultAsyncReader(poDS, nXOff, nYOff, nXSize, nYSize, pBuf, |
274 | 0 | nBufXSize, nBufYSize, eBufType, |
275 | 0 | nBandCount, panBandMap, nPixelSpace, |
276 | 0 | nLineSpace, nBandSpace, papszOptions); |
277 | 0 | } |
278 | | |
279 | | /************************************************************************/ |
280 | | /* GDALDefaultAsyncReader() */ |
281 | | /************************************************************************/ |
282 | | |
283 | | GDALDefaultAsyncReader::GDALDefaultAsyncReader( |
284 | | GDALDataset *poDSIn, int nXOffIn, int nYOffIn, int nXSizeIn, int nYSizeIn, |
285 | | void *pBufIn, int nBufXSizeIn, int nBufYSizeIn, GDALDataType eBufTypeIn, |
286 | | int nBandCountIn, int *panBandMapIn, int nPixelSpaceIn, int nLineSpaceIn, |
287 | | int nBandSpaceIn, CSLConstList papszOptionsIn) |
288 | | |
289 | 0 | { |
290 | 0 | poDS = poDSIn; |
291 | 0 | nXOff = nXOffIn; |
292 | 0 | nYOff = nYOffIn; |
293 | 0 | nXSize = nXSizeIn; |
294 | 0 | nYSize = nYSizeIn; |
295 | 0 | pBuf = pBufIn; |
296 | 0 | nBufXSize = nBufXSizeIn; |
297 | 0 | nBufYSize = nBufYSizeIn; |
298 | 0 | eBufType = eBufTypeIn; |
299 | 0 | nBandCount = nBandCountIn; |
300 | 0 | panBandMap = static_cast<int *>(CPLMalloc(sizeof(int) * nBandCountIn)); |
301 | |
|
302 | 0 | if (panBandMapIn != nullptr) |
303 | 0 | memcpy(panBandMap, panBandMapIn, sizeof(int) * nBandCount); |
304 | 0 | else |
305 | 0 | { |
306 | 0 | for (int i = 0; i < nBandCount; i++) |
307 | 0 | panBandMap[i] = i + 1; |
308 | 0 | } |
309 | |
|
310 | 0 | nPixelSpace = nPixelSpaceIn; |
311 | 0 | nLineSpace = nLineSpaceIn; |
312 | 0 | nBandSpace = nBandSpaceIn; |
313 | |
|
314 | 0 | papszOptions = CSLDuplicate(papszOptionsIn); |
315 | 0 | } |
316 | | |
317 | | /************************************************************************/ |
318 | | /* ~GDALDefaultAsyncReader() */ |
319 | | /************************************************************************/ |
320 | | |
321 | | GDALDefaultAsyncReader::~GDALDefaultAsyncReader() |
322 | | |
323 | 0 | { |
324 | 0 | CPLFree(panBandMap); |
325 | 0 | CSLDestroy(papszOptions); |
326 | 0 | } |
327 | | |
328 | | /************************************************************************/ |
329 | | /* GetNextUpdatedRegion() */ |
330 | | /************************************************************************/ |
331 | | |
332 | | GDALAsyncStatusType |
333 | | GDALDefaultAsyncReader::GetNextUpdatedRegion(double /*dfTimeout*/, |
334 | | int *pnBufXOff, int *pnBufYOff, |
335 | | int *pnBufXSize, int *pnBufYSize) |
336 | 0 | { |
337 | 0 | CPLErr eErr; |
338 | |
|
339 | 0 | eErr = |
340 | 0 | poDS->RasterIO(GF_Read, nXOff, nYOff, nXSize, nYSize, pBuf, nBufXSize, |
341 | 0 | nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, |
342 | 0 | nLineSpace, nBandSpace, nullptr); |
343 | |
|
344 | 0 | *pnBufXOff = 0; |
345 | 0 | *pnBufYOff = 0; |
346 | 0 | *pnBufXSize = nBufXSize; |
347 | 0 | *pnBufYSize = nBufYSize; |
348 | |
|
349 | 0 | if (eErr == CE_None) |
350 | 0 | return GARIO_COMPLETE; |
351 | 0 | else |
352 | 0 | return GARIO_ERROR; |
353 | 0 | } |