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