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-11-21 22:18:42 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()
      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 :     if (osAccess == "r")
      76             :         poDS =
      77           2 :             GDALDataset::FromHandle(GDALOpen(osFilename.c_str(), GA_ReadOnly));
      78             :     else
      79           0 :         poDS = GDALDataset::FromHandle(GDALOpen(osFilename.c_str(), GA_Update));
      80             : 
      81           2 :     if (poDS == nullptr)
      82           2 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
      83             : 
      84           0 :     return new GDAL_EDBFile(poDS);
      85             : }
      86             : 
      87             : /************************************************************************/
      88             : /*                               Close()                                */
      89             : /************************************************************************/
      90             : 
      91           0 : int GDAL_EDBFile::Close() const
      92             : 
      93             : {
      94           0 :     if (poDS != nullptr)
      95             :     {
      96           0 :         delete poDS;
      97           0 :         const_cast<GDAL_EDBFile *>(this)->poDS = nullptr;
      98             :     }
      99             : 
     100           0 :     return 1;
     101             : }
     102             : 
     103             : /************************************************************************/
     104             : /*                              GetWidth()                              */
     105             : /************************************************************************/
     106             : 
     107           0 : int GDAL_EDBFile::GetWidth() const
     108             : 
     109             : {
     110           0 :     return poDS->GetRasterXSize();
     111             : }
     112             : 
     113             : /************************************************************************/
     114             : /*                             GetHeight()                              */
     115             : /************************************************************************/
     116             : 
     117           0 : int GDAL_EDBFile::GetHeight() const
     118             : 
     119             : {
     120           0 :     return poDS->GetRasterYSize();
     121             : }
     122             : 
     123             : /************************************************************************/
     124             : /*                            GetChannels()                             */
     125             : /************************************************************************/
     126             : 
     127           0 : int GDAL_EDBFile::GetChannels() const
     128             : 
     129             : {
     130           0 :     return poDS->GetRasterCount();
     131             : }
     132             : 
     133             : /************************************************************************/
     134             : /*                           GetBlockWidth()                            */
     135             : /************************************************************************/
     136             : 
     137           0 : int GDAL_EDBFile::GetBlockWidth(int nChannel) const
     138             : 
     139             : {
     140             :     int nWidth, nHeight;
     141             : 
     142           0 :     poDS->GetRasterBand(nChannel)->GetBlockSize(&nWidth, &nHeight);
     143             : 
     144           0 :     return nWidth;
     145             : }
     146             : 
     147             : /************************************************************************/
     148             : /*                           GetBlockHeight()                           */
     149             : /************************************************************************/
     150             : 
     151           0 : int GDAL_EDBFile::GetBlockHeight(int nChannel) const
     152             : 
     153             : {
     154             :     int nWidth, nHeight;
     155             : 
     156           0 :     poDS->GetRasterBand(nChannel)->GetBlockSize(&nWidth, &nHeight);
     157             : 
     158           0 :     return nHeight;
     159             : }
     160             : 
     161             : /************************************************************************/
     162             : /*                              GetType()                               */
     163             : /************************************************************************/
     164             : 
     165           0 : eChanType GDAL_EDBFile::GetType(int nChannel) const
     166             : {
     167           0 :     switch (poDS->GetRasterBand(nChannel)->GetRasterDataType())
     168             :     {
     169           0 :         case GDT_Byte:
     170           0 :             return CHN_8U;
     171             : 
     172           0 :         case GDT_Int16:
     173           0 :             return CHN_16S;
     174             : 
     175           0 :         case GDT_UInt16:
     176           0 :             return CHN_16U;
     177             : 
     178           0 :         case GDT_Float32:
     179           0 :             return CHN_32R;
     180             : 
     181           0 :         case GDT_CInt16:
     182           0 :             return CHN_C16S;
     183             : 
     184           0 :         default:
     185           0 :             return CHN_UNKNOWN;
     186             :     }
     187             : }
     188             : 
     189             : /************************************************************************/
     190             : /*                             ReadBlock()                              */
     191             : /************************************************************************/
     192             : 
     193           0 : int GDAL_EDBFile::ReadBlock(int channel, int block_index, void *buffer,
     194             :                             int win_xoff, int win_yoff, int win_xsize,
     195             :                             int win_ysize)
     196             : 
     197             : {
     198           0 :     GDALRasterBand *poBand = poDS->GetRasterBand(channel);
     199             : 
     200           0 :     if (GetType(channel) == CHN_UNKNOWN)
     201             :     {
     202           0 :         ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
     203             :                              GDALGetDataTypeName(poBand->GetRasterDataType()));
     204             :     }
     205             : 
     206             :     int nBlockXSize, nBlockYSize;
     207           0 :     poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     208             : 
     209             :     const int nWidthInBlocks =
     210           0 :         (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
     211             : 
     212           0 :     const int nBlockX = block_index % nWidthInBlocks;
     213           0 :     const int nBlockY = block_index / nWidthInBlocks;
     214             : 
     215             :     const int nPixelOffset =
     216           0 :         GDALGetDataTypeSize(poBand->GetRasterDataType()) / 8;
     217           0 :     const int nLineOffset = win_xsize * nPixelOffset;
     218             : 
     219             :     /* -------------------------------------------------------------------- */
     220             :     /*      Are we reading a partial block at the edge of the database?     */
     221             :     /*      If so, ensure we don't read off the database.                   */
     222             :     /* -------------------------------------------------------------------- */
     223           0 :     if (nBlockX * nBlockXSize + win_xoff + win_xsize > poBand->GetXSize())
     224           0 :         win_xsize = poBand->GetXSize() - nBlockX * nBlockXSize - win_xoff;
     225             : 
     226           0 :     if (nBlockY * nBlockYSize + win_yoff + win_ysize > poBand->GetYSize())
     227           0 :         win_ysize = poBand->GetYSize() - nBlockY * nBlockYSize - win_yoff;
     228             : 
     229           0 :     const CPLErr eErr = poBand->RasterIO(
     230           0 :         GF_Read, nBlockX * nBlockXSize + win_xoff,
     231           0 :         nBlockY * nBlockYSize + win_yoff, win_xsize, win_ysize, buffer,
     232             :         win_xsize, win_ysize, poBand->GetRasterDataType(), nPixelOffset,
     233             :         nLineOffset, nullptr);
     234             : 
     235           0 :     if (eErr != CE_None)
     236             :     {
     237           0 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
     238             :     }
     239             : 
     240           0 :     return 1;
     241             : }
     242             : 
     243             : /************************************************************************/
     244             : /*                             WriteBlock()                             */
     245             : /************************************************************************/
     246             : 
     247           0 : int GDAL_EDBFile::WriteBlock(int channel, int block_index, void *buffer)
     248             : 
     249             : {
     250           0 :     GDALRasterBand *poBand = poDS->GetRasterBand(channel);
     251             : 
     252           0 :     if (GetType(channel) == CHN_UNKNOWN)
     253             :     {
     254           0 :         ThrowPCIDSKException("%s channel type not supported for PCIDSK access.",
     255             :                              GDALGetDataTypeName(poBand->GetRasterDataType()));
     256             :     }
     257             : 
     258             :     int nBlockXSize, nBlockYSize;
     259           0 :     poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     260             : 
     261             :     const int nWidthInBlocks =
     262           0 :         (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
     263             : 
     264           0 :     const int nBlockX = block_index % nWidthInBlocks;
     265           0 :     const int nBlockY = block_index / nWidthInBlocks;
     266             : 
     267             :     /* -------------------------------------------------------------------- */
     268             :     /*      Are we reading a partial block at the edge of the database?     */
     269             :     /*      If so, ensure we don't read off the database.                   */
     270             :     /* -------------------------------------------------------------------- */
     271             :     int nWinXSize, nWinYSize;
     272             : 
     273           0 :     if (nBlockX * nBlockXSize + nBlockXSize > poBand->GetXSize())
     274           0 :         nWinXSize = poBand->GetXSize() - nBlockX * nBlockXSize;
     275             :     else
     276           0 :         nWinXSize = nBlockXSize;
     277             : 
     278           0 :     if (nBlockY * nBlockYSize + nBlockYSize > poBand->GetYSize())
     279           0 :         nWinYSize = poBand->GetYSize() - nBlockY * nBlockYSize;
     280             :     else
     281           0 :         nWinYSize = nBlockYSize;
     282             : 
     283             :     const CPLErr eErr =
     284           0 :         poBand->RasterIO(GF_Write, nBlockX * nBlockXSize, nBlockY * nBlockYSize,
     285             :                          nWinXSize, nWinYSize, buffer, nWinXSize, nWinYSize,
     286             :                          poBand->GetRasterDataType(), 0, 0, nullptr);
     287             : 
     288           0 :     if (eErr != CE_None)
     289             :     {
     290           0 :         ThrowPCIDSKException("%s", CPLGetLastErrorMsg());
     291             :     }
     292             : 
     293           0 :     return 1;
     294             : }

Generated by: LCOV version 1.14