LCOV - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidskbitmap.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 146 44 30.1 %
Date: 2012-04-28 Functions: 35 11 31.4 %

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

Generated by: LCOV version 1.7