LCOV - code coverage report
Current view: top level - gcore - gdalrescaledalphaband.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 38 44 86.4 %
Date: 2024-11-21 22:18:42 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Core
       4             :  * Purpose:  Implementation of GDALRescaledAlphaBand, a class implementing
       5             :  *           a band mask based from a non-GDT_Byte alpha band
       6             :  * Author:   Even Rouault, <even dot rouault at spatialys dot com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys dot com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_port.h"
      15             : #include "gdal_priv.h"
      16             : 
      17             : #include <cstddef>
      18             : 
      19             : #include "cpl_error.h"
      20             : #include "cpl_vsi.h"
      21             : #include "gdal.h"
      22             : 
      23             : //! @cond Doxygen_Suppress
      24             : /************************************************************************/
      25             : /*                        GDALRescaledAlphaBand()                       */
      26             : /************************************************************************/
      27             : 
      28          58 : GDALRescaledAlphaBand::GDALRescaledAlphaBand(GDALRasterBand *poParentIn)
      29          58 :     : poParent(poParentIn), pTemp(nullptr)
      30             : {
      31          58 :     CPLAssert(poParent->GetRasterDataType() == GDT_UInt16);
      32             : 
      33             :     // Defined in GDALRasterBand.
      34          58 :     poDS = nullptr;
      35          58 :     nBand = 0;
      36             : 
      37          58 :     nRasterXSize = poParent->GetXSize();
      38          58 :     nRasterYSize = poParent->GetYSize();
      39             : 
      40          58 :     eDataType = GDT_Byte;
      41          58 :     poParent->GetBlockSize(&nBlockXSize, &nBlockYSize);
      42          58 : }
      43             : 
      44             : /************************************************************************/
      45             : /*                      ~GDALRescaledAlphaBand()                        */
      46             : /************************************************************************/
      47             : 
      48         116 : GDALRescaledAlphaBand::~GDALRescaledAlphaBand()
      49             : {
      50          58 :     VSIFree(pTemp);
      51         116 : }
      52             : 
      53             : /************************************************************************/
      54             : /*                             IReadBlock()                             */
      55             : /************************************************************************/
      56             : 
      57           1 : CPLErr GDALRescaledAlphaBand::IReadBlock(int nXBlockOff, int nYBlockOff,
      58             :                                          void *pImage)
      59             : {
      60           1 :     int nXSizeRequest = nBlockXSize;
      61           1 :     if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize)
      62           0 :         nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize;
      63           1 :     int nYSizeRequest = nBlockYSize;
      64           1 :     if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize)
      65           0 :         nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize;
      66             : 
      67             :     GDALRasterIOExtraArg sExtraArg;
      68           1 :     INIT_RASTERIO_EXTRA_ARG(sExtraArg);
      69             : 
      70           1 :     return IRasterIO(GF_Read, nXBlockOff * nBlockXSize,
      71           1 :                      nYBlockOff * nBlockYSize, nXSizeRequest, nYSizeRequest,
      72             :                      pImage, nXSizeRequest, nYSizeRequest, GDT_Byte, 1,
      73           2 :                      nBlockXSize, &sExtraArg);
      74             : }
      75             : 
      76             : /************************************************************************/
      77             : /*                             IRasterIO()                              */
      78             : /************************************************************************/
      79             : 
      80         204 : CPLErr GDALRescaledAlphaBand::IRasterIO(
      81             :     GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
      82             :     void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
      83             :     GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg)
      84             : {
      85             :     // Optimization in common use case.
      86             :     // This avoids triggering the block cache on this band, which helps
      87             :     // reducing the global block cache consumption.
      88         204 :     if (eRWFlag == GF_Read && eBufType == GDT_Byte && nXSize == nBufXSize &&
      89         204 :         nYSize == nBufYSize && nPixelSpace == 1)
      90             :     {
      91         204 :         if (pTemp == nullptr)
      92             :         {
      93          12 :             pTemp = VSI_MALLOC2_VERBOSE(sizeof(GUInt16), nRasterXSize);
      94          12 :             if (pTemp == nullptr)
      95             :             {
      96           0 :                 return CE_Failure;
      97             :             }
      98             :         }
      99         417 :         for (int j = 0; j < nBufYSize; j++)
     100             :         {
     101             :             const CPLErr eErr =
     102         213 :                 poParent->RasterIO(GF_Read, nXOff, nYOff + j, nXSize, 1, pTemp,
     103             :                                    nBufXSize, 1, GDT_UInt16, 0, 0, nullptr);
     104         213 :             if (eErr != CE_None)
     105           0 :                 return eErr;
     106             : 
     107         213 :             GByte *pabyImage = static_cast<GByte *>(pData) + j * nLineSpace;
     108         213 :             GUInt16 *pSrc = static_cast<GUInt16 *>(pTemp);
     109             : 
     110        5216 :             for (int i = 0; i < nBufXSize; i++)
     111             :             {
     112             :                 // In case the dynamics was actually 0-255 and not 0-65535 as
     113             :                 // expected, we want to make sure non-zero alpha will still
     114             :                 // be non-zero.
     115        5003 :                 if (pSrc[i] > 0 && pSrc[i] < 257)
     116        4001 :                     pabyImage[i] = 1;
     117             :                 else
     118        1002 :                     pabyImage[i] = static_cast<GByte>((pSrc[i] * 255) / 65535);
     119             :             }
     120             :         }
     121         204 :         return CE_None;
     122             :     }
     123             : 
     124           0 :     return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize,
     125             :                                      pData, nBufXSize, nBufYSize, eBufType,
     126           0 :                                      nPixelSpace, nLineSpace, psExtraArg);
     127             : }
     128             : 
     129             : //! @endcond

Generated by: LCOV version 1.14