LCOV - code coverage report
Current view: top level - frmts/pcidsk - gdal_edb.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 7 86 8.1 %
Date: 2026-06-19 21:24:00 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             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_conv.h"
      14             : #include "cpl_multiproc.h"
      15             : #include "gdal_priv.h"
      16             : #include "pcidsk.h"
      17             : 
      18             : using PCIDSK::CHN_16S;
      19             : using PCIDSK::CHN_16U;
      20             : using PCIDSK::CHN_32R;
      21             : using PCIDSK::CHN_8U;
      22             : using PCIDSK::CHN_C16S;
      23             : using PCIDSK::CHN_UNKNOWN;
      24             : using PCIDSK::eChanType;
      25             : using PCIDSK::EDBFile;
      26             : using PCIDSK::ThrowPCIDSKException;
      27             : 
      28             : EDBFile *GDAL_EDBOpen(const std::string &osFilename,
      29             :                       const std::string &osAccess);
      30             : 
      31             : /************************************************************************/
      32             : /* ==================================================================== */
      33             : /*                            GDAL_EDBFile                              */
      34             : /* ==================================================================== */
      35             : /************************************************************************/
      36             : 
      37             : class GDAL_EDBFile final : public EDBFile
      38             : {
      39             :     GDALDataset *poDS;
      40             : 
      41             :   public:
      42           0 :     explicit GDAL_EDBFile(GDALDataset *poDSIn)
      43           0 :     {
      44           0 :         poDS = poDSIn;
      45           0 :     }
      46             : 
      47           0 :     ~GDAL_EDBFile() override
      48           0 :     {
      49           0 :         if (poDS)
      50           0 :             GDAL_EDBFile::Close();
      51           0 :     }
      52             : 
      53             :     int Close() const override;
      54             :     int GetWidth() const override;
      55             :     int GetHeight() const override;
      56             :     int GetChannels() const override;
      57             :     int GetBlockWidth(int channel) const override;
      58             :     int GetBlockHeight(int channel) const override;
      59             :     eChanType GetType(int channel) const override;
      60             :     int ReadBlock(int channel, int block_index, void *buffer, int win_xoff,
      61             :                   int win_yoff, int win_xsize, int win_ysize) override;
      62             :     int WriteBlock(int channel, int block_index, void *buffer) override;
      63             : };
      64             : 
      65             : /************************************************************************/
      66             : /*                            GDAL_EDBOpen()                            */
      67             : /************************************************************************/
      68             : 
      69           2 : EDBFile *GDAL_EDBOpen(const std::string &osFilename,
      70             :                       const std::string &osAccess)
      71             : 
      72             : {
      73           2 :     GDALDataset *poDS = nullptr;
      74             : 
      75           2 :     const int nFlags = (osAccess == "r") ? GDAL_OF_READONLY : GDAL_OF_UPDATE;
      76           2 :     poDS = GDALDataset::Open(osFilename.c_str(),
      77           2 :                              nFlags | GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR);
      78           2 :     if (poDS == nullptr)
      79           2 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
      80             : 
      81           0 :     return new GDAL_EDBFile(poDS);
      82             : }
      83             : 
      84             : /************************************************************************/
      85             : /*                               Close()                                */
      86             : /************************************************************************/
      87             : 
      88           0 : int GDAL_EDBFile::Close() const
      89             : 
      90             : {
      91           0 :     if (poDS != nullptr)
      92             :     {
      93           0 :         delete poDS;
      94           0 :         const_cast<GDAL_EDBFile *>(this)->poDS = nullptr;
      95             :     }
      96             : 
      97           0 :     return 1;
      98             : }
      99             : 
     100             : /************************************************************************/
     101             : /*                              GetWidth()                              */
     102             : /************************************************************************/
     103             : 
     104           0 : int GDAL_EDBFile::GetWidth() const
     105             : 
     106             : {
     107           0 :     return poDS->GetRasterXSize();
     108             : }
     109             : 
     110             : /************************************************************************/
     111             : /*                             GetHeight()                              */
     112             : /************************************************************************/
     113             : 
     114           0 : int GDAL_EDBFile::GetHeight() const
     115             : 
     116             : {
     117           0 :     return poDS->GetRasterYSize();
     118             : }
     119             : 
     120             : /************************************************************************/
     121             : /*                            GetChannels()                             */
     122             : /************************************************************************/
     123             : 
     124           0 : int GDAL_EDBFile::GetChannels() const
     125             : 
     126             : {
     127           0 :     return poDS->GetRasterCount();
     128             : }
     129             : 
     130             : /************************************************************************/
     131             : /*                           GetBlockWidth()                            */
     132             : /************************************************************************/
     133             : 
     134           0 : int GDAL_EDBFile::GetBlockWidth(int nChannel) const
     135             : 
     136             : {
     137             :     int nWidth, nHeight;
     138             : 
     139           0 :     poDS->GetRasterBand(nChannel)->GetBlockSize(&nWidth, &nHeight);
     140             : 
     141           0 :     return nWidth;
     142             : }
     143             : 
     144             : /************************************************************************/
     145             : /*                           GetBlockHeight()                           */
     146             : /************************************************************************/
     147             : 
     148           0 : int GDAL_EDBFile::GetBlockHeight(int nChannel) const
     149             : 
     150             : {
     151             :     int nWidth, nHeight;
     152             : 
     153           0 :     poDS->GetRasterBand(nChannel)->GetBlockSize(&nWidth, &nHeight);
     154             : 
     155           0 :     return nHeight;
     156             : }
     157             : 
     158             : /************************************************************************/
     159             : /*                              GetType()                               */
     160             : /************************************************************************/
     161             : 
     162           0 : eChanType GDAL_EDBFile::GetType(int nChannel) const
     163             : {
     164           0 :     switch (poDS->GetRasterBand(nChannel)->GetRasterDataType())
     165             :     {
     166           0 :         case GDT_UInt8:
     167           0 :             return CHN_8U;
     168             : 
     169           0 :         case GDT_Int16:
     170           0 :             return CHN_16S;
     171             : 
     172           0 :         case GDT_UInt16:
     173           0 :             return CHN_16U;
     174             : 
     175           0 :         case GDT_Float32:
     176           0 :             return CHN_32R;
     177             : 
     178           0 :         case GDT_CInt16:
     179           0 :             return CHN_C16S;
     180             : 
     181           0 :         default:
     182           0 :             return CHN_UNKNOWN;
     183             :     }
     184             : }
     185             : 
     186             : /************************************************************************/
     187             : /*                             ReadBlock()                              */
     188             : /************************************************************************/
     189             : 
     190           0 : int GDAL_EDBFile::ReadBlock(int channel, int block_index, void *buffer,
     191             :                             int win_xoff, int win_yoff, int win_xsize,
     192             :                             int win_ysize)
     193             : 
     194             : {
     195           0 :     GDALRasterBand *poBand = poDS->GetRasterBand(channel);
     196             : 
     197           0 :     if (GetType(channel) == CHN_UNKNOWN)
     198             :     {
     199           0 :         ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
     200             :                              GDALGetDataTypeName(poBand->GetRasterDataType()));
     201             :     }
     202             : 
     203             :     int nBlockXSize, nBlockYSize;
     204           0 :     poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     205             : 
     206           0 :     const int nWidthInBlocks = DIV_ROUND_UP(poBand->GetXSize(), nBlockXSize);
     207             : 
     208           0 :     const int nBlockX = block_index % nWidthInBlocks;
     209           0 :     const int nBlockY = block_index / nWidthInBlocks;
     210             : 
     211             :     const int nPixelOffset =
     212           0 :         GDALGetDataTypeSizeBytes(poBand->GetRasterDataType());
     213           0 :     const int nLineOffset = win_xsize * nPixelOffset;
     214             : 
     215             :     /* -------------------------------------------------------------------- */
     216             :     /*      Are we reading a partial block at the edge of the database?     */
     217             :     /*      If so, ensure we don't read off the database.                   */
     218             :     /* -------------------------------------------------------------------- */
     219           0 :     if (nBlockX * nBlockXSize + win_xoff + win_xsize > poBand->GetXSize())
     220           0 :         win_xsize = poBand->GetXSize() - nBlockX * nBlockXSize - win_xoff;
     221             : 
     222           0 :     if (nBlockY * nBlockYSize + win_yoff + win_ysize > poBand->GetYSize())
     223           0 :         win_ysize = poBand->GetYSize() - nBlockY * nBlockYSize - win_yoff;
     224             : 
     225           0 :     const CPLErr eErr = poBand->RasterIO(
     226           0 :         GF_Read, nBlockX * nBlockXSize + win_xoff,
     227           0 :         nBlockY * nBlockYSize + win_yoff, win_xsize, win_ysize, buffer,
     228             :         win_xsize, win_ysize, poBand->GetRasterDataType(), nPixelOffset,
     229             :         nLineOffset, nullptr);
     230             : 
     231           0 :     if (eErr != CE_None)
     232             :     {
     233           0 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
     234             :     }
     235             : 
     236           0 :     return 1;
     237             : }
     238             : 
     239             : /************************************************************************/
     240             : /*                             WriteBlock()                             */
     241             : /************************************************************************/
     242             : 
     243           0 : int GDAL_EDBFile::WriteBlock(int channel, int block_index, void *buffer)
     244             : 
     245             : {
     246           0 :     GDALRasterBand *poBand = poDS->GetRasterBand(channel);
     247             : 
     248           0 :     if (GetType(channel) == CHN_UNKNOWN)
     249             :     {
     250           0 :         ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
     251             :                              GDALGetDataTypeName(poBand->GetRasterDataType()));
     252             :     }
     253             : 
     254             :     int nBlockXSize, nBlockYSize;
     255           0 :     poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     256             : 
     257           0 :     const int nWidthInBlocks = DIV_ROUND_UP(poBand->GetXSize(), nBlockXSize);
     258             : 
     259           0 :     const int nBlockX = block_index % nWidthInBlocks;
     260           0 :     const int nBlockY = block_index / nWidthInBlocks;
     261             : 
     262             :     /* -------------------------------------------------------------------- */
     263             :     /*      Are we reading a partial block at the edge of the database?     */
     264             :     /*      If so, ensure we don't read off the database.                   */
     265             :     /* -------------------------------------------------------------------- */
     266             :     int nWinXSize, nWinYSize;
     267             : 
     268           0 :     if (nBlockX * nBlockXSize + nBlockXSize > poBand->GetXSize())
     269           0 :         nWinXSize = poBand->GetXSize() - nBlockX * nBlockXSize;
     270             :     else
     271           0 :         nWinXSize = nBlockXSize;
     272             : 
     273           0 :     if (nBlockY * nBlockYSize + nBlockYSize > poBand->GetYSize())
     274           0 :         nWinYSize = poBand->GetYSize() - nBlockY * nBlockYSize;
     275             :     else
     276           0 :         nWinYSize = nBlockYSize;
     277             : 
     278             :     const CPLErr eErr =
     279           0 :         poBand->RasterIO(GF_Write, nBlockX * nBlockXSize, nBlockY * nBlockYSize,
     280             :                          nWinXSize, nWinYSize, buffer, nWinXSize, nWinYSize,
     281             :                          poBand->GetRasterDataType(), 0, 0, nullptr);
     282             : 
     283           0 :     if (eErr != CE_None)
     284             :     {
     285           0 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
     286             :     }
     287             : 
     288           0 :     return 1;
     289             : }

Generated by: LCOV version 1.14