LCOV - code coverage report
Current view: top level - frmts/pcidsk - gdal_edb.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 6 86 7.0 %
Date: 2024-04-27 17:22:41 Functions: 1 13 7.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PCIDSK Database File
       4             :  * Purpose:  External Database access interface implementation (EDBFile).
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2010, Frank Warmerdam <warmerdam@pobox.com>
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "cpl_conv.h"
      30             : #include "cpl_multiproc.h"
      31             : #include "gdal_priv.h"
      32             : #include "pcidsk.h"
      33             : 
      34             : using PCIDSK::CHN_16S;
      35             : using PCIDSK::CHN_16U;
      36             : using PCIDSK::CHN_32R;
      37             : using PCIDSK::CHN_8U;
      38             : using PCIDSK::CHN_C16S;
      39             : using PCIDSK::CHN_UNKNOWN;
      40             : using PCIDSK::eChanType;
      41             : using PCIDSK::EDBFile;
      42             : using PCIDSK::ThrowPCIDSKException;
      43             : 
      44             : EDBFile *GDAL_EDBOpen(const std::string &osFilename,
      45             :                       const std::string &osAccess);
      46             : 
      47             : /************************************************************************/
      48             : /* ==================================================================== */
      49             : /*                            GDAL_EDBFile                              */
      50             : /* ==================================================================== */
      51             : /************************************************************************/
      52             : 
      53             : class GDAL_EDBFile final : public EDBFile
      54             : {
      55             :     GDALDataset *poDS;
      56             : 
      57             :   public:
      58           0 :     explicit GDAL_EDBFile(GDALDataset *poDSIn)
      59           0 :     {
      60           0 :         poDS = poDSIn;
      61           0 :     }
      62             : 
      63           0 :     ~GDAL_EDBFile()
      64           0 :     {
      65           0 :         if (poDS)
      66           0 :             GDAL_EDBFile::Close();
      67           0 :     }
      68             : 
      69             :     int Close() const override;
      70             :     int GetWidth() const override;
      71             :     int GetHeight() const override;
      72             :     int GetChannels() const override;
      73             :     int GetBlockWidth(int channel) const override;
      74             :     int GetBlockHeight(int channel) const override;
      75             :     eChanType GetType(int channel) const override;
      76             :     int ReadBlock(int channel, int block_index, void *buffer, int win_xoff,
      77             :                   int win_yoff, int win_xsize, int win_ysize) override;
      78             :     int WriteBlock(int channel, int block_index, void *buffer) override;
      79             : };
      80             : 
      81             : /************************************************************************/
      82             : /*                            GDAL_EDBOpen()                            */
      83             : /************************************************************************/
      84             : 
      85           2 : EDBFile *GDAL_EDBOpen(const std::string &osFilename,
      86             :                       const std::string &osAccess)
      87             : 
      88             : {
      89           2 :     GDALDataset *poDS = nullptr;
      90             : 
      91           2 :     if (osAccess == "r")
      92             :         poDS =
      93           2 :             GDALDataset::FromHandle(GDALOpen(osFilename.c_str(), GA_ReadOnly));
      94             :     else
      95           0 :         poDS = GDALDataset::FromHandle(GDALOpen(osFilename.c_str(), GA_Update));
      96             : 
      97           2 :     if (poDS == nullptr)
      98           2 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
      99             : 
     100           0 :     return new GDAL_EDBFile(poDS);
     101             : }
     102             : 
     103             : /************************************************************************/
     104             : /*                               Close()                                */
     105             : /************************************************************************/
     106             : 
     107           0 : int GDAL_EDBFile::Close() const
     108             : 
     109             : {
     110           0 :     if (poDS != nullptr)
     111             :     {
     112           0 :         delete poDS;
     113           0 :         const_cast<GDAL_EDBFile *>(this)->poDS = nullptr;
     114             :     }
     115             : 
     116           0 :     return 1;
     117             : }
     118             : 
     119             : /************************************************************************/
     120             : /*                              GetWidth()                              */
     121             : /************************************************************************/
     122             : 
     123           0 : int GDAL_EDBFile::GetWidth() const
     124             : 
     125             : {
     126           0 :     return poDS->GetRasterXSize();
     127             : }
     128             : 
     129             : /************************************************************************/
     130             : /*                             GetHeight()                              */
     131             : /************************************************************************/
     132             : 
     133           0 : int GDAL_EDBFile::GetHeight() const
     134             : 
     135             : {
     136           0 :     return poDS->GetRasterYSize();
     137             : }
     138             : 
     139             : /************************************************************************/
     140             : /*                            GetChannels()                             */
     141             : /************************************************************************/
     142             : 
     143           0 : int GDAL_EDBFile::GetChannels() const
     144             : 
     145             : {
     146           0 :     return poDS->GetRasterCount();
     147             : }
     148             : 
     149             : /************************************************************************/
     150             : /*                           GetBlockWidth()                            */
     151             : /************************************************************************/
     152             : 
     153           0 : int GDAL_EDBFile::GetBlockWidth(int nChannel) const
     154             : 
     155             : {
     156             :     int nWidth, nHeight;
     157             : 
     158           0 :     poDS->GetRasterBand(nChannel)->GetBlockSize(&nWidth, &nHeight);
     159             : 
     160           0 :     return nWidth;
     161             : }
     162             : 
     163             : /************************************************************************/
     164             : /*                           GetBlockHeight()                           */
     165             : /************************************************************************/
     166             : 
     167           0 : int GDAL_EDBFile::GetBlockHeight(int nChannel) const
     168             : 
     169             : {
     170             :     int nWidth, nHeight;
     171             : 
     172           0 :     poDS->GetRasterBand(nChannel)->GetBlockSize(&nWidth, &nHeight);
     173             : 
     174           0 :     return nHeight;
     175             : }
     176             : 
     177             : /************************************************************************/
     178             : /*                              GetType()                               */
     179             : /************************************************************************/
     180             : 
     181           0 : eChanType GDAL_EDBFile::GetType(int nChannel) const
     182             : {
     183           0 :     switch (poDS->GetRasterBand(nChannel)->GetRasterDataType())
     184             :     {
     185           0 :         case GDT_Byte:
     186           0 :             return CHN_8U;
     187             : 
     188           0 :         case GDT_Int16:
     189           0 :             return CHN_16S;
     190             : 
     191           0 :         case GDT_UInt16:
     192           0 :             return CHN_16U;
     193             : 
     194           0 :         case GDT_Float32:
     195           0 :             return CHN_32R;
     196             : 
     197           0 :         case GDT_CInt16:
     198           0 :             return CHN_C16S;
     199             : 
     200           0 :         default:
     201           0 :             return CHN_UNKNOWN;
     202             :     }
     203             : }
     204             : 
     205             : /************************************************************************/
     206             : /*                             ReadBlock()                              */
     207             : /************************************************************************/
     208             : 
     209           0 : int GDAL_EDBFile::ReadBlock(int channel, int block_index, void *buffer,
     210             :                             int win_xoff, int win_yoff, int win_xsize,
     211             :                             int win_ysize)
     212             : 
     213             : {
     214           0 :     GDALRasterBand *poBand = poDS->GetRasterBand(channel);
     215             : 
     216           0 :     if (GetType(channel) == CHN_UNKNOWN)
     217             :     {
     218           0 :         ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
     219             :                              GDALGetDataTypeName(poBand->GetRasterDataType()));
     220             :     }
     221             : 
     222             :     int nBlockXSize, nBlockYSize;
     223           0 :     poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     224             : 
     225             :     const int nWidthInBlocks =
     226           0 :         (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
     227             : 
     228           0 :     const int nBlockX = block_index % nWidthInBlocks;
     229           0 :     const int nBlockY = block_index / nWidthInBlocks;
     230             : 
     231             :     const int nPixelOffset =
     232           0 :         GDALGetDataTypeSize(poBand->GetRasterDataType()) / 8;
     233           0 :     const int nLineOffset = win_xsize * nPixelOffset;
     234             : 
     235             :     /* -------------------------------------------------------------------- */
     236             :     /*      Are we reading a partial block at the edge of the database?     */
     237             :     /*      If so, ensure we don't read off the database.                   */
     238             :     /* -------------------------------------------------------------------- */
     239           0 :     if (nBlockX * nBlockXSize + win_xoff + win_xsize > poBand->GetXSize())
     240           0 :         win_xsize = poBand->GetXSize() - nBlockX * nBlockXSize - win_xoff;
     241             : 
     242           0 :     if (nBlockY * nBlockYSize + win_yoff + win_ysize > poBand->GetYSize())
     243           0 :         win_ysize = poBand->GetYSize() - nBlockY * nBlockYSize - win_yoff;
     244             : 
     245           0 :     const CPLErr eErr = poBand->RasterIO(
     246           0 :         GF_Read, nBlockX * nBlockXSize + win_xoff,
     247           0 :         nBlockY * nBlockYSize + win_yoff, win_xsize, win_ysize, buffer,
     248             :         win_xsize, win_ysize, poBand->GetRasterDataType(), nPixelOffset,
     249             :         nLineOffset, nullptr);
     250             : 
     251           0 :     if (eErr != CE_None)
     252             :     {
     253           0 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
     254             :     }
     255             : 
     256           0 :     return 1;
     257             : }
     258             : 
     259             : /************************************************************************/
     260             : /*                             WriteBlock()                             */
     261             : /************************************************************************/
     262             : 
     263           0 : int GDAL_EDBFile::WriteBlock(int channel, int block_index, void *buffer)
     264             : 
     265             : {
     266           0 :     GDALRasterBand *poBand = poDS->GetRasterBand(channel);
     267             : 
     268           0 :     if (GetType(channel) == CHN_UNKNOWN)
     269             :     {
     270           0 :         ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
     271             :                              GDALGetDataTypeName(poBand->GetRasterDataType()));
     272             :     }
     273             : 
     274             :     int nBlockXSize, nBlockYSize;
     275           0 :     poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     276             : 
     277             :     const int nWidthInBlocks =
     278           0 :         (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
     279             : 
     280           0 :     const int nBlockX = block_index % nWidthInBlocks;
     281           0 :     const int nBlockY = block_index / nWidthInBlocks;
     282             : 
     283             :     /* -------------------------------------------------------------------- */
     284             :     /*      Are we reading a partial block at the edge of the database?     */
     285             :     /*      If so, ensure we don't read off the database.                   */
     286             :     /* -------------------------------------------------------------------- */
     287             :     int nWinXSize, nWinYSize;
     288             : 
     289           0 :     if (nBlockX * nBlockXSize + nBlockXSize > poBand->GetXSize())
     290           0 :         nWinXSize = poBand->GetXSize() - nBlockX * nBlockXSize;
     291             :     else
     292           0 :         nWinXSize = nBlockXSize;
     293             : 
     294           0 :     if (nBlockY * nBlockYSize + nBlockYSize > poBand->GetYSize())
     295           0 :         nWinYSize = poBand->GetYSize() - nBlockY * nBlockYSize;
     296             :     else
     297           0 :         nWinYSize = nBlockYSize;
     298             : 
     299             :     const CPLErr eErr =
     300           0 :         poBand->RasterIO(GF_Write, nBlockX * nBlockXSize, nBlockY * nBlockYSize,
     301             :                          nWinXSize, nWinYSize, buffer, nWinXSize, nWinYSize,
     302             :                          poBand->GetRasterDataType(), 0, 0, nullptr);
     303             : 
     304           0 :     if (eErr != CE_None)
     305             :     {
     306           0 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
     307             :     }
     308             : 
     309           0 :     return 1;
     310             : }

Generated by: LCOV version 1.14