LCOV - code coverage report
Current view: directory - frmts/pcidsk/sdk/channel - cbandinterleavedchannel.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 76 50 65.8 %
Date: 2010-01-09 Functions: 5 5 100.0 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CBandInterleavedChannel class.
       4                 :  *
       5                 :  * This class is used to implement band interleaved channels within a 
       6                 :  * PCIDSK file (which are always packed, and FILE interleaved data from
       7                 :  * external raw files which may not be packed. 
       8                 :  * 
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2009
      11                 :  * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, Canada
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "pcidsk_config.h"
      33                 : #include "pcidsk_types.h"
      34                 : #include "pcidsk_channel.h"
      35                 : #include "pcidsk_buffer.h"
      36                 : #include "pcidsk_exception.h"
      37                 : #include "pcidsk_file.h"
      38                 : #include "core/pcidsk_utils.h"
      39                 : #include "core/cpcidskfile.h"
      40                 : #include "channel/cbandinterleavedchannel.h"
      41                 : #include <cassert>
      42                 : #include <cstring>
      43                 : #include <cstdio>
      44                 : 
      45                 : using namespace PCIDSK;
      46                 : 
      47                 : /************************************************************************/
      48                 : /*                      CBandInterleavedChannel()                       */
      49                 : /************************************************************************/
      50                 : 
      51             124 : CBandInterleavedChannel::CBandInterleavedChannel( PCIDSKBuffer &image_header, 
      52                 :                                                   PCIDSKBuffer &file_header,
      53                 :                                                   int channelnum,
      54                 :                                                   CPCIDSKFile *file,
      55                 :                                                   uint64 image_offset,
      56                 :                                                   eChanType pixel_type )
      57             124 :         : CPCIDSKChannel( image_header, file, pixel_type, channelnum )
      58                 : 
      59                 : {
      60             124 :     io_handle_p = NULL;
      61             124 :     io_mutex_p = NULL;
      62                 : 
      63                 : /* -------------------------------------------------------------------- */
      64                 : /*      Establish the data layout.                                      */
      65                 : /* -------------------------------------------------------------------- */
      66             124 :     if( strcmp(file->GetInterleaving().c_str(),"FILE") == 0 )
      67                 :     {
      68               0 :         start_byte = atouint64(image_header.Get( 168, 16 ));
      69               0 :         pixel_offset = atouint64(image_header.Get( 184, 8 ));
      70               0 :         line_offset = atouint64(image_header.Get( 192, 8 ));
      71                 :     }
      72                 :     else
      73                 :     {
      74             124 :         start_byte = image_offset;
      75             124 :         pixel_offset = DataTypeSize(pixel_type);
      76             124 :         line_offset = pixel_offset * width;
      77                 :     }
      78                 : 
      79                 : /* -------------------------------------------------------------------- */
      80                 : /*      Establish the file we will be accessing.                        */
      81                 : /* -------------------------------------------------------------------- */
      82             124 :     image_header.Get(64,64,filename);
      83                 : 
      84             124 :     if( filename.length() == 0 )
      85             124 :         file->GetIODetails( &io_handle_p, &io_mutex_p );
      86             124 : }
      87                 : 
      88                 : /************************************************************************/
      89                 : /*                      ~CBandInterleavedChannel()                      */
      90                 : /************************************************************************/
      91                 : 
      92             248 : CBandInterleavedChannel::~CBandInterleavedChannel()
      93                 : 
      94                 : {
      95             248 : }
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                             ReadBlock()                              */
      99                 : /************************************************************************/
     100                 : 
     101              81 : int CBandInterleavedChannel::ReadBlock( int block_index, void *buffer,
     102                 :                                         int xoff, int yoff, 
     103                 :                                         int xsize, int ysize )
     104                 : 
     105                 : {
     106              81 :     PCIDSKInterfaces *interfaces = file->GetInterfaces();
     107                 : 
     108                 : /* -------------------------------------------------------------------- */
     109                 : /*      Default window if needed.                                       */
     110                 : /* -------------------------------------------------------------------- */
     111              81 :     if( xoff == -1 && yoff == -1 && xsize == -1 && ysize == -1 )
     112                 :     {
     113              81 :         xoff = 0;
     114              81 :         yoff = 0;
     115              81 :         xsize = GetBlockWidth();
     116              81 :         ysize = GetBlockHeight();
     117                 :     }
     118                 : 
     119                 : /* -------------------------------------------------------------------- */
     120                 : /*      Validate Window                                                 */
     121                 : /* -------------------------------------------------------------------- */
     122             162 :     if( xoff < 0 || xoff + xsize > GetBlockWidth()
     123              81 :         || yoff < 0 || yoff + ysize > GetBlockHeight() )
     124                 :     {
     125                 :         ThrowPCIDSKException( 
     126                 :             "Invalid window in ReadBloc(): xoff=%d,yoff=%d,xsize=%d,ysize=%d",
     127               0 :             xoff, yoff, xsize, ysize );
     128                 :     }
     129                 : 
     130                 : /* -------------------------------------------------------------------- */
     131                 : /*      Establish region to read.                                       */
     132                 : /* -------------------------------------------------------------------- */
     133              81 :     int    pixel_size = DataTypeSize( pixel_type );
     134                 :     uint64 offset = start_byte + line_offset * block_index
     135              81 :         + pixel_offset * xoff;
     136              81 :     int    window_size = (int) (pixel_offset*(xsize-1) + pixel_size);
     137                 : 
     138                 : /* -------------------------------------------------------------------- */
     139                 : /*      Get file access handles if we don't already have them.          */
     140                 : /* -------------------------------------------------------------------- */
     141              81 :     if( io_handle_p == NULL )
     142               0 :         file->GetIODetails( &io_handle_p, &io_mutex_p, filename.c_str() );
     143                 : 
     144                 : /* -------------------------------------------------------------------- */
     145                 : /*      If the imagery is packed, we can read directly into the         */
     146                 : /*      target buffer.                                                  */
     147                 : /* -------------------------------------------------------------------- */
     148              81 :     if( pixel_size == (int) pixel_offset )
     149                 :     {
     150              81 :         MutexHolder holder( *io_mutex_p );
     151                 : 
     152              81 :         interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
     153              81 :         interfaces->io->Read( buffer, 1, window_size, *io_handle_p );
     154                 :     }
     155                 : 
     156                 : /* -------------------------------------------------------------------- */
     157                 : /*      Otherwise we allocate a working buffer that holds the whole     */
     158                 : /*      line, read into that, and pick out our data of interest.        */
     159                 : /* -------------------------------------------------------------------- */
     160                 :     else
     161                 :     {
     162                 :         int  i;
     163               0 :         PCIDSKBuffer line_from_disk( window_size );
     164                 :         char *this_pixel;
     165                 : 
     166               0 :         MutexHolder holder( *io_mutex_p );
     167                 :         
     168               0 :         interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
     169                 :         interfaces->io->Read( buffer, 1, line_from_disk.buffer_size, 
     170               0 :                               *io_handle_p );
     171                 : 
     172               0 :         for( i = 0, this_pixel = line_from_disk.buffer; i < xsize; i++ )
     173                 :         {
     174                 :             memcpy( ((char *) buffer) + pixel_size * i, 
     175               0 :                     this_pixel, pixel_size );
     176               0 :             this_pixel += pixel_size;
     177               0 :         }
     178                 :     }
     179                 : 
     180                 : /* -------------------------------------------------------------------- */
     181                 : /*      Do byte swapping if needed.                                     */
     182                 : /* -------------------------------------------------------------------- */
     183              81 :     if( needs_swap )
     184              60 :         SwapData( buffer, pixel_size, xsize );
     185                 : 
     186              81 :     return 1;
     187                 : }
     188                 : 
     189                 : /************************************************************************/
     190                 : /*                             WriteBlock()                             */
     191                 : /************************************************************************/
     192                 : 
     193             317 : int CBandInterleavedChannel::WriteBlock( int block_index, void *buffer )
     194                 : 
     195                 : {
     196             317 :     PCIDSKInterfaces *interfaces = file->GetInterfaces();
     197                 : 
     198             317 :     if( !file->GetUpdatable() )
     199               0 :         throw PCIDSKException( "File not open for update in WriteBlock()" );
     200                 : 
     201                 : /* -------------------------------------------------------------------- */
     202                 : /*      Establish region to read.                                       */
     203                 : /* -------------------------------------------------------------------- */
     204             317 :     int    pixel_size = DataTypeSize( pixel_type );
     205             317 :     uint64 offset = start_byte + line_offset * block_index;
     206             317 :     int    window_size = (int) (pixel_offset*(width-1) + pixel_size);
     207                 : 
     208                 : /* -------------------------------------------------------------------- */
     209                 : /*      Get file access handles if we don't already have them.          */
     210                 : /* -------------------------------------------------------------------- */
     211             317 :     if( io_handle_p == NULL )
     212               0 :         file->GetIODetails( &io_handle_p, &io_mutex_p, filename.c_str() );
     213                 : 
     214                 : /* -------------------------------------------------------------------- */
     215                 : /*      If the imagery is packed, we can read directly into the         */
     216                 : /*      target buffer.                                                  */
     217                 : /* -------------------------------------------------------------------- */
     218             317 :     if( pixel_size == (int) pixel_offset )
     219                 :     {
     220             317 :         MutexHolder holder( *io_mutex_p );
     221                 : 
     222             317 :         if( needs_swap ) // swap before write.
     223              90 :             SwapData( buffer, pixel_size, width );
     224                 : 
     225             317 :         interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
     226             317 :         interfaces->io->Write( buffer, 1, window_size, *io_handle_p );
     227                 : 
     228             317 :         if( needs_swap ) // restore to original order.
     229              90 :             SwapData( buffer, pixel_size, width );
     230                 :     }
     231                 : 
     232                 : /* -------------------------------------------------------------------- */
     233                 : /*      Otherwise we allocate a working buffer that holds the whole     */
     234                 : /*      line, read into that, and pick out our data of interest.        */
     235                 : /* -------------------------------------------------------------------- */
     236                 :     else
     237                 :     {
     238                 :         int  i;
     239               0 :         PCIDSKBuffer line_from_disk( window_size );
     240                 :         char *this_pixel;
     241                 : 
     242               0 :         MutexHolder holder( *io_mutex_p );
     243                 :         
     244               0 :         interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
     245                 :         interfaces->io->Read( buffer, 1, line_from_disk.buffer_size, 
     246               0 :                               *io_handle_p );
     247                 : 
     248               0 :         for( i = 0, this_pixel = line_from_disk.buffer; i < width; i++ )
     249                 :         {
     250                 :             memcpy( this_pixel, ((char *) buffer) + pixel_size * i, 
     251               0 :                     pixel_size );
     252                 : 
     253               0 :             if( needs_swap ) // swap before write.
     254               0 :                 SwapData( this_pixel, pixel_size, 1 );
     255                 : 
     256               0 :             this_pixel += pixel_size;
     257                 :         }
     258                 : 
     259               0 :         interfaces->io->Seek( *io_handle_p, offset, SEEK_SET );
     260                 :         interfaces->io->Write( buffer, 1, line_from_disk.buffer_size, 
     261               0 :                                *io_handle_p );
     262                 :     }
     263                 : 
     264                 : /* -------------------------------------------------------------------- */
     265                 : /*      Do byte swapping if needed.                                     */
     266                 : /* -------------------------------------------------------------------- */
     267                 : 
     268             317 :     return 1;
     269                 : }
     270                 : 

Generated by: LCOV version 1.7