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