LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/segment - cpcidskbitmap.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 156 0.0 %
Date: 2025-07-01 22:47:05 Functions: 0 35 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Purpose:  Implementation of the CPCIDSKBitmap class.
       4             :  *
       5             :  ******************************************************************************
       6             :  * Copyright (c) 2010
       7             :  * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #include "pcidsk_exception.h"
      13             : #include "segment/cpcidskbitmap.h"
      14             : #include "pcidsk_file.h"
      15             : #include "core/pcidsk_utils.h"
      16             : #include <cassert>
      17             : #include <cstring>
      18             : #include <cstdlib>
      19             : #include <cstdio>
      20             : #include <cctype>
      21             : 
      22             : using namespace PCIDSK;
      23             : 
      24             : /************************************************************************/
      25             : /*                           CPCIDSKBitmap()                            */
      26             : /************************************************************************/
      27             : 
      28           0 : CPCIDSKBitmap::CPCIDSKBitmap( PCIDSKFile *fileIn, int segmentIn,
      29           0 :                               const char *segment_pointer )
      30           0 :         : CPCIDSKSegment( fileIn, segmentIn, segment_pointer )
      31             : 
      32             : {
      33           0 :     loaded = false;
      34           0 :     width = 0;
      35           0 :     height = 0;
      36           0 :     block_width = 0;
      37           0 :     block_height = 0;
      38           0 : }
      39             : 
      40             : /************************************************************************/
      41             : /*                           ~CPCIDSKBitmap()                           */
      42             : /************************************************************************/
      43             : 
      44           0 : CPCIDSKBitmap::~CPCIDSKBitmap()
      45             : 
      46             : {
      47           0 : }
      48             : 
      49             : /************************************************************************/
      50             : /*                             Initialize()                             */
      51             : /*                                                                      */
      52             : /*      Set up a newly created bitmap segment.  We just need to         */
      53             : /*      write some stuff into the segment header.                       */
      54             : /************************************************************************/
      55             : 
      56           0 : void CPCIDSKBitmap::Initialize()
      57             : 
      58             : {
      59           0 :     loaded = false;
      60             : 
      61           0 :     CPCIDSKBitmap *pThis = (CPCIDSKBitmap *) this;
      62             : 
      63           0 :     PCIDSKBuffer &bheader = pThis->GetHeader();
      64             : 
      65           0 :     bheader.Put( 0, 160     , 16 );
      66           0 :     bheader.Put( 0, 160+16*1, 16 );
      67           0 :     bheader.Put( file->GetWidth(), 160+16*2, 16 );
      68           0 :     bheader.Put( file->GetHeight(), 160+16*3, 16 );
      69           0 :     bheader.Put( -1, 160+16*4, 16 );
      70             : 
      71           0 :     file->WriteToFile( bheader.buffer, data_offset, 1024 );
      72           0 : }
      73             : 
      74             : /************************************************************************/
      75             : /*                                Load()                                */
      76             : /************************************************************************/
      77             : 
      78           0 : void CPCIDSKBitmap::Load() const
      79             : 
      80             : {
      81           0 :     if( loaded )
      82           0 :         return;
      83             : 
      84             :     // We don't really mean the internals are const, just a lie to
      85             :     // keep the const interfaces happy.
      86             : 
      87           0 :     CPCIDSKBitmap *pThis = (CPCIDSKBitmap *) this;
      88             : 
      89           0 :     PCIDSKBuffer &bheader = pThis->GetHeader();
      90             : 
      91           0 :     pThis->width  = bheader.GetInt( 192,    16 );
      92           0 :     pThis->height = bheader.GetInt( 192+16, 16 );
      93             : 
      94             :     // Choosing 8 lines per block ensures that each block
      95             :     // starts on a byte boundary.
      96           0 :     pThis->block_width = pThis->width;
      97           0 :     pThis->block_height = 8;
      98             : 
      99           0 :     pThis->loaded = true;
     100             : }
     101             : 
     102             : /************************************************************************/
     103             : /*                           GetBlockWidth()                            */
     104             : /************************************************************************/
     105             : 
     106           0 : int CPCIDSKBitmap::GetBlockWidth() const
     107             : 
     108             : {
     109           0 :     if( !loaded )
     110           0 :         Load();
     111             : 
     112           0 :     return block_width;
     113             : }
     114             : 
     115             : /************************************************************************/
     116             : /*                           GetBlockHeight()                           */
     117             : /************************************************************************/
     118             : 
     119           0 : int CPCIDSKBitmap::GetBlockHeight() const
     120             : 
     121             : {
     122           0 :     if( !loaded )
     123           0 :         Load();
     124             : 
     125           0 :     return block_height;
     126             : }
     127             : 
     128             : /************************************************************************/
     129             : /*                           GetBlockCount()                            */
     130             : /************************************************************************/
     131             : 
     132           0 : int CPCIDSKBitmap::GetBlockCount() const
     133             : 
     134             : {
     135           0 :     if( !loaded )
     136           0 :         Load();
     137             : 
     138           0 :     return DIV_ROUND_UP(width, block_width) * DIV_ROUND_UP(height, block_height);
     139             : }
     140             : 
     141             : /************************************************************************/
     142             : /*                              GetWidth()                              */
     143             : /************************************************************************/
     144             : 
     145           0 : int CPCIDSKBitmap::GetWidth() const
     146             : 
     147             : {
     148           0 :     if( !loaded )
     149           0 :         Load();
     150             : 
     151           0 :     return width;
     152             : }
     153             : 
     154             : /************************************************************************/
     155             : /*                             GetHeight()                              */
     156             : /************************************************************************/
     157             : 
     158           0 : int CPCIDSKBitmap::GetHeight() const
     159             : 
     160             : {
     161           0 :     if( !loaded )
     162           0 :         Load();
     163             : 
     164           0 :     return height;
     165             : }
     166             : 
     167             : /************************************************************************/
     168             : /*                              GetType()                               */
     169             : /************************************************************************/
     170             : 
     171           0 : eChanType CPCIDSKBitmap::GetType() const
     172             : 
     173             : {
     174           0 :     return CHN_BIT;
     175             : }
     176             : 
     177             : /************************************************************************/
     178             : /*                          PCIDSK_CopyBits()                           */
     179             : /*                                                                      */
     180             : /*      Copy bit strings - adapted from GDAL.                           */
     181             : /************************************************************************/
     182             : 
     183             : static void
     184           0 : PCIDSK_CopyBits( const uint8 *pabySrcData, int nSrcOffset, int nSrcStep,
     185             :                  uint8 *pabyDstData, int nDstOffset, int nDstStep,
     186             :                  int nBitCount, int nStepCount )
     187             : 
     188             : {
     189             :     int iStep;
     190             :     int iBit;
     191             : 
     192           0 :     for( iStep = 0; iStep < nStepCount; iStep++ )
     193             :     {
     194           0 :         for( iBit = 0; iBit < nBitCount; iBit++ )
     195             :         {
     196           0 :             if( pabySrcData[nSrcOffset>>3]
     197           0 :                 & (0x80 >>(nSrcOffset & 7)) )
     198           0 :                 pabyDstData[nDstOffset>>3] |= (0x80 >> (nDstOffset & 7));
     199             :             else
     200           0 :                 pabyDstData[nDstOffset>>3] &= ~(0x80 >> (nDstOffset & 7));
     201             : 
     202             : 
     203           0 :             nSrcOffset++;
     204           0 :             nDstOffset++;
     205             :         }
     206             : 
     207           0 :         nSrcOffset += (nSrcStep - nBitCount);
     208           0 :         nDstOffset += (nDstStep - nBitCount);
     209             :     }
     210           0 : }
     211             : 
     212             : /************************************************************************/
     213             : /*                             ReadBlock()                              */
     214             : /************************************************************************/
     215             : 
     216           0 : int CPCIDSKBitmap::ReadBlock( int block_index, void *buffer,
     217             :                               int win_xoff, int win_yoff,
     218             :                               int win_xsize, int win_ysize )
     219             : 
     220             : {
     221           0 :     uint64 block_size = (static_cast<uint64>(block_width) * block_height + 7) / 8;
     222           0 :     uint8 *wrk_buffer = (uint8 *) buffer;
     223             : 
     224           0 :     if( block_index < 0 || block_index >= GetBlockCount() )
     225             :     {
     226           0 :         return ThrowPCIDSKException(0, "Requested non-existent block (%d)",
     227           0 :                               block_index );
     228             :     }
     229             : /* -------------------------------------------------------------------- */
     230             : /*      If we are doing subwindowing, we will need to create a          */
     231             : /*      temporary bitmap to load into.  If we are concerned about       */
     232             : /*      high performance access to small windows in big bitmaps we      */
     233             : /*      will eventually want to reimplement this to avoid reading       */
     234             : /*      the whole block to subwindow from.                              */
     235             : /* -------------------------------------------------------------------- */
     236           0 :     if( win_ysize != -1 )
     237             :     {
     238           0 :         if( win_xoff < 0 || win_xoff + win_xsize > GetBlockWidth()
     239           0 :             || win_yoff < 0 || win_yoff + win_ysize > GetBlockHeight() )
     240             :         {
     241           0 :             return ThrowPCIDSKException( 0,
     242             :                 "Invalid window in CPCIDSKBitmap::ReadBlock(): xoff=%d,yoff=%d,xsize=%d,ysize=%d",
     243           0 :                 win_xoff, win_yoff, win_xsize, win_ysize );
     244             :         }
     245             : 
     246           0 :         wrk_buffer = (uint8 *) malloc((size_t) block_size);
     247           0 :         if( wrk_buffer == nullptr )
     248           0 :             return ThrowPCIDSKException(0, "Out of memory allocating %d bytes in CPCIDSKBitmap::ReadBlock()",
     249           0 :                                   (int) block_size );
     250             :     }
     251             : 
     252             : /* -------------------------------------------------------------------- */
     253             : /*      Read the block, taking care in the case of partial blocks at    */
     254             : /*      the bottom of the image.                                        */
     255             : /* -------------------------------------------------------------------- */
     256           0 :     if( (block_index+1) * block_height <= height )
     257           0 :         ReadFromFile( wrk_buffer, block_size * block_index, block_size );
     258             :     else
     259             :     {
     260             :         uint64 short_block_size;
     261             : 
     262           0 :         memset( buffer, 0, (size_t) block_size );
     263             : 
     264           0 :         short_block_size =
     265           0 :             (static_cast<uint64>(height - block_index*block_height) * block_width + 7) / 8;
     266             : 
     267           0 :         ReadFromFile( wrk_buffer, block_size * block_index, short_block_size );
     268             :     }
     269             : 
     270             : /* -------------------------------------------------------------------- */
     271             : /*      Perform subwindowing if needed.                                 */
     272             : /* -------------------------------------------------------------------- */
     273           0 :     if( win_ysize != -1 )
     274             :     {
     275             :         int y_out;
     276             : 
     277           0 :         for( y_out = 0; y_out <  win_ysize; y_out++ )
     278             :         {
     279           0 :             PCIDSK_CopyBits( wrk_buffer,
     280           0 :                              win_xoff + (y_out+win_yoff)*block_width, 0,
     281             :                              (uint8*) buffer, y_out * win_xsize, 0,
     282             :                              win_xsize, 1 );
     283             :         }
     284             : 
     285           0 :         free( wrk_buffer );
     286             :     }
     287             : 
     288           0 :     return 0;
     289             : }
     290             : 
     291             : /************************************************************************/
     292             : /*                             WriteBlock()                             */
     293             : /************************************************************************/
     294             : 
     295           0 : int CPCIDSKBitmap::WriteBlock( int block_index, void *buffer )
     296             : 
     297             : {
     298           0 :     uint64 block_size = (static_cast<uint64>(block_width) * block_height) / 8;
     299             : 
     300           0 :     if( (block_index+1) * block_height <= height )
     301           0 :         WriteToFile( buffer, block_size * block_index, block_size );
     302             :     else
     303             :     {
     304             :         uint64 short_block_size;
     305             : 
     306           0 :         short_block_size =
     307           0 :             (static_cast<uint64>(height - block_index*block_height) * block_width + 7) / 8;
     308             : 
     309           0 :         WriteToFile( buffer, block_size * block_index, short_block_size );
     310             :     }
     311             : 
     312           0 :     return 1;
     313             : }
     314             : 
     315             : /************************************************************************/
     316             : /*                          GetOverviewCount()                          */
     317             : /************************************************************************/
     318             : 
     319           0 : int CPCIDSKBitmap::GetOverviewCount()
     320             : {
     321           0 :     return 0;
     322             : }
     323             : 
     324             : /************************************************************************/
     325             : /*                            GetOverview()                             */
     326             : /************************************************************************/
     327             : 
     328           0 : PCIDSKChannel *CPCIDSKBitmap::GetOverview( int i )
     329             : {
     330           0 :     return (PCIDSKChannel*) ThrowPCIDSKExceptionPtr("Non-existent overview %d requested on bitmap segment.", i);
     331             : }
     332             : 
     333             : /************************************************************************/
     334             : /*                          IsOverviewValid()                           */
     335             : /************************************************************************/
     336             : 
     337           0 : bool CPCIDSKBitmap::IsOverviewValid( CPL_UNUSED int i )
     338             : {
     339           0 :     return false;
     340             : }
     341             : 
     342             : /************************************************************************/
     343             : /*                       GetOverviewResampling()                        */
     344             : /************************************************************************/
     345             : 
     346           0 : std::string CPCIDSKBitmap::GetOverviewResampling( CPL_UNUSED int i )
     347             : {
     348           0 :     return "";
     349             : }
     350             : 
     351             : /************************************************************************/
     352             : /*                        SetOverviewValidity()                         */
     353             : /************************************************************************/
     354             : 
     355           0 : void CPCIDSKBitmap::SetOverviewValidity( CPL_UNUSED int i, CPL_UNUSED bool validity )
     356             : {
     357           0 : }
     358             : 
     359             : /************************************************************************/
     360             : /*                          GetMetadataValue()                          */
     361             : /************************************************************************/
     362             : 
     363           0 : std::string CPCIDSKBitmap::GetMetadataValue( const std::string &key ) const
     364             : 
     365             : {
     366           0 :     return CPCIDSKSegment::GetMetadataValue( key );
     367             : }
     368             : 
     369             : /************************************************************************/
     370             : /*                          SetMetadataValue()                          */
     371             : /************************************************************************/
     372             : 
     373           0 : void CPCIDSKBitmap::SetMetadataValue( const std::string &key,
     374             :                                       const std::string &value )
     375             : 
     376             : {
     377           0 :     CPCIDSKSegment::SetMetadataValue( key, value );
     378           0 : }
     379             : 
     380             : /************************************************************************/
     381             : /*                   GetOverviewLevelMapping()                          */
     382             : /************************************************************************/
     383           0 : std::vector<int> CPCIDSKBitmap::GetOverviewLevelMapping() const
     384             : {
     385           0 :     std::vector<int> ov;
     386             : 
     387           0 :     return ov;
     388             : }
     389             : 
     390             : /************************************************************************/
     391             : /*                          GetMetadataKeys()                           */
     392             : /************************************************************************/
     393             : 
     394           0 : std::vector<std::string> CPCIDSKBitmap::GetMetadataKeys() const
     395             : 
     396             : {
     397           0 :     return CPCIDSKSegment::GetMetadataKeys();
     398             : }
     399             : 
     400             : /************************************************************************/
     401             : /*                            Synchronize()                             */
     402             : /************************************************************************/
     403             : 
     404           0 : void CPCIDSKBitmap::Synchronize()
     405             : 
     406             : {
     407             :     // TODO
     408             : 
     409           0 :     CPCIDSKSegment::Synchronize();
     410           0 : }
     411             : 
     412             : /************************************************************************/
     413             : /*                           GetDescription()                           */
     414             : /************************************************************************/
     415             : 
     416           0 : std::string CPCIDSKBitmap::GetDescription()
     417             : 
     418             : {
     419           0 :     return CPCIDSKSegment::GetDescription();
     420             : }
     421             : 
     422             : /************************************************************************/
     423             : /*                           SetDescription()                           */
     424             : /************************************************************************/
     425             : 
     426           0 : void CPCIDSKBitmap::SetDescription( const std::string &description )
     427             : 
     428             : {
     429           0 :     CPCIDSKSegment::SetDescription( description );
     430           0 : }
     431             : 
     432             : /************************************************************************/
     433             : /*                         GetHistoryEntries()                          */
     434             : /************************************************************************/
     435             : 
     436           0 : std::vector<std::string> CPCIDSKBitmap::GetHistoryEntries() const
     437             : 
     438             : {
     439           0 :     return CPCIDSKSegment::GetHistoryEntries();
     440             : }
     441             : 
     442             : /************************************************************************/
     443             : /*                         SetHistoryEntries()                          */
     444             : /************************************************************************/
     445             : 
     446           0 : void CPCIDSKBitmap::SetHistoryEntries( const std::vector<std::string> &entries )
     447             : 
     448             : {
     449           0 :     CPCIDSKSegment::SetHistoryEntries( entries );
     450           0 : }
     451             : 
     452             : /************************************************************************/
     453             : /*                            PushHistory()                             */
     454             : /************************************************************************/
     455             : 
     456           0 : void CPCIDSKBitmap::PushHistory( const std::string &app,
     457             :                                  const std::string &message )
     458             : 
     459             : {
     460           0 :     CPCIDSKSegment::PushHistory( app, message );
     461           0 : }
     462             : 
     463             : /************************************************************************/
     464             : /*                            GetChanInfo()                             */
     465             : /************************************************************************/
     466           0 : void CPCIDSKBitmap::GetChanInfo( std::string &filename, uint64 &image_offset,
     467             :                                  uint64 &pixel_offset, uint64 &line_offset,
     468             :                                  bool &little_endian ) const
     469             : 
     470             : {
     471           0 :     image_offset = 0;
     472           0 :     pixel_offset = 0;
     473           0 :     line_offset = 0;
     474           0 :     little_endian = true;
     475           0 :     filename = "";
     476           0 : }
     477             : 
     478             : /************************************************************************/
     479             : /*                            SetChanInfo()                             */
     480             : /************************************************************************/
     481             : 
     482           0 : void CPCIDSKBitmap::SetChanInfo( CPL_UNUSED std::string filename, CPL_UNUSED uint64 image_offset,
     483             :                                  CPL_UNUSED uint64 pixel_offset, CPL_UNUSED uint64 line_offset,
     484             :                                  CPL_UNUSED bool little_endian )
     485             : {
     486           0 :     return ThrowPCIDSKException( "Attempt to SetChanInfo() on a bitmap." );
     487             : }
     488             : 
     489             : /************************************************************************/
     490             : /*                            GetEChanInfo()                            */
     491             : /************************************************************************/
     492           0 : void CPCIDSKBitmap::GetEChanInfo( std::string &filename, int &echannel,
     493             :                                   int &exoff, int &eyoff,
     494             :                                   int &exsize, int &eysize ) const
     495             : {
     496           0 :     echannel = 0;
     497           0 :     exoff = 0;
     498           0 :     eyoff = 0;
     499           0 :     exsize = 0;
     500           0 :     eysize = 0;
     501           0 :     filename = "";
     502           0 : }
     503             : 
     504             : /************************************************************************/
     505             : /*                            SetEChanInfo()                            */
     506             : /************************************************************************/
     507             : 
     508           0 : void CPCIDSKBitmap::SetEChanInfo( CPL_UNUSED std::string filename, CPL_UNUSED int echannel,
     509             :                                   CPL_UNUSED int exoff, CPL_UNUSED int eyoff,
     510             :                                   CPL_UNUSED int exsize, CPL_UNUSED int eysize )
     511             : {
     512           0 :     return ThrowPCIDSKException( "Attempt to SetEChanInfo() on a bitmap." );
     513             : }

Generated by: LCOV version 1.14