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 : /************************************************************************/
25 : /* ==================================================================== */
26 : /* GDALAsyncReader */
27 : /* ==================================================================== */
28 : /************************************************************************/
29 :
30 : /************************************************************************/
31 : /* GDALAsyncReader() */
32 : /************************************************************************/
33 :
34 1 : GDALAsyncReader::GDALAsyncReader()
35 : : poDS(nullptr), nXOff(0), nYOff(0), nXSize(0), nYSize(0), pBuf(nullptr),
36 : nBufXSize(0), nBufYSize(0), eBufType(GDT_Unknown), nBandCount(0),
37 1 : panBandMap(nullptr), nPixelSpace(0), nLineSpace(0), nBandSpace(0)
38 : {
39 1 : }
40 :
41 : /************************************************************************/
42 : /* ~GDALAsyncReader() */
43 : /************************************************************************/
44 : 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 1 : GDALAsyncStatusType CPL_STDCALL GDALARGetNextUpdatedRegion(
136 : GDALAsyncReaderH hARIO, double dfTimeout, int *pnBufXOff, int *pnBufYOff,
137 : int *pnBufXSize, int *pnBufYSize)
138 : {
139 1 : VALIDATE_POINTER1(hARIO, "GDALARGetNextUpdatedRegion", GARIO_ERROR);
140 1 : return static_cast<GDALAsyncReader *>(hARIO)->GetNextUpdatedRegion(
141 1 : dfTimeout, pnBufXOff, pnBufYOff, pnBufXSize, pnBufYSize);
142 : }
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 0 : int GDALAsyncReader::LockBuffer(double /* dfTimeout */)
168 : {
169 0 : return TRUE;
170 : }
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 0 : int CPL_STDCALL GDALARLockBuffer(GDALAsyncReaderH hARIO, double dfTimeout)
195 : {
196 0 : VALIDATE_POINTER1(hARIO, "GDALARLockBuffer", FALSE);
197 0 : return static_cast<GDALAsyncReader *>(hARIO)->LockBuffer(dfTimeout);
198 : }
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 0 : void GDALAsyncReader::UnlockBuffer()
211 :
212 : {
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 0 : void CPL_STDCALL GDALARUnlockBuffer(GDALAsyncReaderH hARIO)
230 : {
231 0 : VALIDATE_POINTER0(hARIO, "GDALARUnlockBuffer");
232 0 : static_cast<GDALAsyncReader *>(hARIO)->UnlockBuffer();
233 : }
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 1 : 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 : {
273 : return new GDALDefaultAsyncReader(poDS, nXOff, nYOff, nXSize, nYSize, pBuf,
274 : nBufXSize, nBufYSize, eBufType,
275 : nBandCount, panBandMap, nPixelSpace,
276 1 : nLineSpace, nBandSpace, papszOptions);
277 : }
278 :
279 : /************************************************************************/
280 : /* GDALDefaultAsyncReader() */
281 : /************************************************************************/
282 :
283 1 : 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 1 : int nBandSpaceIn, CSLConstList papszOptionsIn)
288 :
289 : {
290 1 : poDS = poDSIn;
291 1 : nXOff = nXOffIn;
292 1 : nYOff = nYOffIn;
293 1 : nXSize = nXSizeIn;
294 1 : nYSize = nYSizeIn;
295 1 : pBuf = pBufIn;
296 1 : nBufXSize = nBufXSizeIn;
297 1 : nBufYSize = nBufYSizeIn;
298 1 : eBufType = eBufTypeIn;
299 1 : nBandCount = nBandCountIn;
300 1 : panBandMap = static_cast<int *>(CPLMalloc(sizeof(int) * nBandCountIn));
301 :
302 1 : if (panBandMapIn != nullptr)
303 1 : memcpy(panBandMap, panBandMapIn, sizeof(int) * nBandCount);
304 : else
305 : {
306 0 : for (int i = 0; i < nBandCount; i++)
307 0 : panBandMap[i] = i + 1;
308 : }
309 :
310 1 : nPixelSpace = nPixelSpaceIn;
311 1 : nLineSpace = nLineSpaceIn;
312 1 : nBandSpace = nBandSpaceIn;
313 :
314 1 : papszOptions = CSLDuplicate(papszOptionsIn);
315 1 : }
316 :
317 : /************************************************************************/
318 : /* ~GDALDefaultAsyncReader() */
319 : /************************************************************************/
320 :
321 2 : GDALDefaultAsyncReader::~GDALDefaultAsyncReader()
322 :
323 : {
324 1 : CPLFree(panBandMap);
325 1 : CSLDestroy(papszOptions);
326 2 : }
327 :
328 : /************************************************************************/
329 : /* GetNextUpdatedRegion() */
330 : /************************************************************************/
331 :
332 : GDALAsyncStatusType
333 1 : GDALDefaultAsyncReader::GetNextUpdatedRegion(double /*dfTimeout*/,
334 : int *pnBufXOff, int *pnBufYOff,
335 : int *pnBufXSize, int *pnBufYSize)
336 : {
337 : CPLErr eErr;
338 :
339 : eErr =
340 2 : poDS->RasterIO(GF_Read, nXOff, nYOff, nXSize, nYSize, pBuf, nBufXSize,
341 1 : nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace,
342 1 : nLineSpace, nBandSpace, nullptr);
343 :
344 1 : *pnBufXOff = 0;
345 1 : *pnBufYOff = 0;
346 1 : *pnBufXSize = nBufXSize;
347 1 : *pnBufYSize = nBufYSize;
348 :
349 1 : if (eErr == CE_None)
350 1 : return GARIO_COMPLETE;
351 : else
352 0 : return GARIO_ERROR;
353 : }
|