LCOV - code coverage report
Current view: top level - gcore - gdaldefaultasync.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 43 56 76.8 %
Date: 2026-01-31 22:56:34 Functions: 7 11 63.6 %

          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             : }

Generated by: LCOV version 1.14