LCOV - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidsk_array.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 106 0 0.0 %
Date: 2011-12-18 Functions: 16 0 0.0 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CPCIDSK_TEX 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/cpcidsk_array.h"
      30                 : #include "core/cpcidskfile.h"
      31                 : #include <cstring>
      32                 : #include <sstream>
      33                 : #include <cassert>
      34                 : #include "core/pcidsk_utils.h"
      35                 : 
      36                 : using namespace PCIDSK;
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                            CPCIDSK_ARRAY()                           */
      40                 : /************************************************************************/
      41                 : 
      42               0 : CPCIDSK_ARRAY::CPCIDSK_ARRAY( PCIDSKFile *file, int segment,
      43                 :                               const char *segment_pointer )
      44                 :         : CPCIDSKSegment( file, segment, segment_pointer ),
      45               0 :         loaded_(false),mbModified(false)
      46                 : {
      47               0 :     MAX_DIMENSIONS = 8;
      48               0 :     Load();
      49               0 : }
      50                 : 
      51                 : /************************************************************************/
      52                 : /*                            ~CPCIDSK_ARRAY                            */
      53                 : /************************************************************************/
      54                 : 
      55               0 : CPCIDSK_ARRAY::~CPCIDSK_ARRAY()
      56                 : 
      57                 : {
      58               0 : }
      59                 : 
      60                 : /**
      61                 :  * Load the contents of the segment
      62                 :  */
      63               0 : void CPCIDSK_ARRAY::Load()
      64                 : {
      65                 :     // Check if we've already loaded the segment into memory
      66               0 :     if (loaded_) {
      67               0 :         return;
      68                 :     }
      69                 : 
      70               0 :     PCIDSKBuffer& seg_header = this->GetHeader();
      71               0 :     seg_data.SetSize(GetContentSize());
      72               0 :     ReadFromFile(seg_data.buffer, 0, seg_data.buffer_size);
      73                 : 
      74               0 :     if(std::strncmp(seg_header.buffer+160, "64R     ", 8))
      75                 :     {
      76               0 :         seg_header.Put("64R     ",160,8);
      77               0 :         loaded_ = true;
      78               0 :         return ;
      79                 :     }
      80                 : 
      81               0 :     int nDimension = seg_header.GetInt(160+8,8);
      82               0 :     if(nDimension < 1 || nDimension > MAX_DIMENSIONS)
      83                 :     {
      84               0 :         std::stringstream oStream;
      85               0 :         oStream << "Invalid array dimension " << nDimension;
      86               0 :         oStream << " stored in the segment.";
      87               0 :         std::string oMsg = oStream.str();
      88               0 :         throw PCIDSKException(oMsg.c_str());
      89                 :     }
      90               0 :     mnDimension = static_cast<unsigned char>(nDimension);
      91                 : 
      92               0 :     moSizes.clear();
      93               0 :     for( int i = 0; i < mnDimension; i++ )
      94                 :     {
      95               0 :         int nSize = seg_header.GetInt(160+24 + i*8,8);
      96               0 :         if(nSize < 1)
      97                 :         {
      98               0 :             std::stringstream oStream;
      99               0 :             oStream << "Invalid size " << nSize << " for dimension " << i+1;
     100               0 :             std::string oMsg = oStream.str();
     101               0 :             throw PCIDSKException(oMsg.c_str());
     102                 :         }
     103               0 :     moSizes.push_back( nSize );
     104                 :     }
     105                 : 
     106                 :     //calculate the total number of elements in the array.
     107               0 :     unsigned int nElements = 1;
     108               0 :     for(unsigned int i=0 ; i < moSizes.size() ; i++)
     109                 :     {
     110               0 :         nElements *= moSizes[i];
     111                 :     }
     112                 :     
     113               0 :     for( unsigned int i = 0; i < nElements; i++ )
     114                 :     {
     115               0 :         const double* pdValue = (const double*)seg_data.Get(i*8,8);
     116                 :         char uValue[8];
     117               0 :         std::memcpy(uValue,pdValue,8);
     118               0 :         SwapData(uValue,8,1);
     119               0 :         double dValue = *((double*)uValue);
     120               0 :         moArray.push_back(dValue);
     121                 :     }
     122                 : 
     123                 :     //PCIDSK doesn't have support for headers.
     124                 : 
     125                 :     // We've now loaded the structure up with data. Mark it as being loaded 
     126                 :     // properly.
     127               0 :     loaded_ = true;
     128                 :     
     129                 : }
     130                 : 
     131                 : /**
     132                 :  * Write the segment on disk
     133                 :  */
     134               0 : void CPCIDSK_ARRAY::Write(void)
     135                 : {
     136                 :     //We are not writing if nothing was loaded.
     137               0 :     if (!loaded_) {
     138               0 :         return;
     139                 :     }
     140                 : 
     141               0 :     PCIDSKBuffer& seg_header = this->GetHeader();
     142               0 :     int nBlocks = (moArray.size()*8 + 511)/512 ;
     143               0 :     unsigned int nSizeBuffer = (nBlocks)*512 ;
     144                 :     //64 values can be put into 512 bytes.
     145               0 :     unsigned int nRest = nBlocks*64 - moArray.size();
     146                 : 
     147               0 :     seg_data.SetSize(nSizeBuffer);
     148                 : 
     149               0 :     seg_header.Put("64R     ",160,8);
     150               0 :     seg_header.Put((int)mnDimension,160+8,8);
     151                 : 
     152               0 :     for( int i = 0; i < mnDimension; i++ )
     153                 :     {
     154               0 :         int nSize = static_cast<int>(moSizes[i]);
     155               0 :         seg_header.Put(nSize,160+24 + i*8,8);
     156                 :     }
     157                 : 
     158               0 :     for( unsigned int i = 0; i < moArray.size(); i++ )
     159                 :     {
     160               0 :         double dValue = moArray[i];
     161               0 :         SwapData(&dValue,8,1);
     162               0 :         seg_data.PutBin(dValue,i*8);
     163                 :     }
     164                 : 
     165                 :     //set the end of the buffer to 0.
     166               0 :     for( unsigned int i=0 ; i < nRest ; i++)
     167                 :     {
     168               0 :         seg_data.Put(0.0,(moArray.size()+i)*8,8,"%22.14f");
     169                 :     }
     170                 : 
     171               0 :     WriteToFile(seg_data.buffer,0,seg_data.buffer_size);
     172                 : 
     173               0 :     mbModified = false;
     174                 : }
     175                 : 
     176                 : /**
     177                 :  * Synchronize the segement, if it was modified then
     178                 :  * write it into disk.
     179                 :  */
     180               0 : void CPCIDSK_ARRAY::Synchronize()
     181                 : {
     182               0 :     if(mbModified)
     183                 :     {
     184               0 :         this->Write();
     185                 :         //write the modified header
     186               0 :         file->WriteToFile( header.buffer, data_offset, 1024 );
     187                 :     }
     188               0 : }
     189                 : 
     190                 : /**
     191                 :  * This function returns the number of dimension in the array.
     192                 :  * an array segment can have minimum 1 dimension and maximum
     193                 :  * 8 dimension.
     194                 :  *
     195                 :  * @return the dimension of the array in [1,8]
     196                 :  */
     197               0 : unsigned char CPCIDSK_ARRAY::GetDimensionCount() const 
     198                 : {
     199               0 :     return mnDimension;
     200                 : }
     201                 : 
     202                 : /**
     203                 :  * This function set the dimension of the array. the dimension
     204                 :  * must be in [1,8] or a pci::Exception is thrown.
     205                 :  *
     206                 :  * @param nDim number of dimension, should be in [1,8]
     207                 :  */
     208               0 : void CPCIDSK_ARRAY::SetDimensionCount(unsigned char nDim) 
     209                 : {
     210               0 :     if(nDim < 1 || nDim > 8)
     211                 :     {
     212                 :         throw PCIDSKException("An array cannot have a "
     213               0 :             "dimension bigger than 8 or smaller than 1.");
     214                 :     }
     215               0 :     mnDimension = nDim;
     216               0 :     mbModified = true;
     217               0 : }
     218                 : 
     219                 : /**
     220                 :  * Get the number of element that can be put in each of the dimension
     221                 :  * of the array. the size of the return vector is GetDimensionCount().
     222                 :  *
     223                 :  * @return the size of each dimension.
     224                 :  */
     225               0 : const std::vector<unsigned int>& CPCIDSK_ARRAY::GetSizes() const 
     226                 : {
     227               0 :     return moSizes;
     228                 : }
     229                 : 
     230                 : /**
     231                 :  * Set the size of each dimension. If the size of the array is bigger
     232                 :  * or smaller than GetDimensionCount(), then a pci::Exception is thrown
     233                 :  * if one of the sizes is 0, then a pci::Exception is thrown.
     234                 :  *
     235                 :  * @param oSizes the size of each dimension 
     236                 :  */
     237               0 : void CPCIDSK_ARRAY::SetSizes(const std::vector<unsigned int>& oSizes) 
     238                 : {
     239               0 :     if(oSizes.size() != GetDimensionCount())
     240                 :     {
     241                 :         throw PCIDSKException("You need to specify the sizes"
     242               0 :             " for each dimension of the array");
     243                 :     }
     244                 : 
     245               0 :     for( unsigned int i=0 ; i < oSizes.size() ; i++)
     246                 :     {
     247               0 :         if(oSizes[i] == 0)
     248                 :         {
     249               0 :             throw PCIDSKException("You cannot define the size of a dimension to 0.");
     250                 :         }
     251                 :     }
     252               0 :     moSizes = oSizes;
     253               0 :     mbModified = true;
     254               0 : }
     255                 : 
     256                 : /**
     257                 :  * Get the array in a vector. the size of this vector is
     258                 :  * GetSize()[0]*GetSize()[2]*...*GetSize()[GetDimensionCount()-1].
     259                 :  * value are stored in the following order inside this vector:
     260                 :  * ViDj = Value i of Dimension j
     261                 :  * n = size of dimension 1
     262                 :  * p = size of dimension 2
     263                 :  * h = size of dimension k
     264                 :  *
     265                 :  * V1D1 ... VnD1 V1D2 ... VpD2 ... V1Dk ... VhDk 
     266                 :  *
     267                 :  * @return the array.
     268                 :  */
     269               0 : const std::vector<double>& CPCIDSK_ARRAY::GetArray() const 
     270                 : {
     271               0 :     return moArray;
     272                 : }
     273                 : 
     274                 : /**
     275                 :  * Set the array in the segment. the size of this vector is
     276                 :  * GetSize()[0]*GetSize()[2]*...*GetSize()[GetDimensionCount()-1].
     277                 :  * value are stored in the following order inside this vector:
     278                 :  * ViDj = Value i of Dimension j
     279                 :  * n = size of dimension 1
     280                 :  * p = size of dimension 2
     281                 :  * h = size of dimension k
     282                 :  *
     283                 :  * V1D1 ... VnD1 V1D2 ... VpD2 ... V1Dk ... VhDk 
     284                 :  *
     285                 :  * If the size of oArray doesn't match the sizes and dimensions
     286                 :  * then a pci::Exception is thrown.
     287                 :  *
     288                 :  * @param oArray the array.
     289                 :  */
     290               0 : void CPCIDSK_ARRAY::SetArray(const std::vector<double>& oArray) 
     291                 : {
     292               0 :     unsigned int nLength = 1;
     293               0 :     for( unsigned int i=0 ; i < moSizes.size() ; i++)
     294                 :     {
     295               0 :         nLength *= moSizes[i];
     296                 :     }
     297                 : 
     298               0 :     if(nLength != oArray.size())
     299                 :     {
     300                 :         throw PCIDSKException("the size of this array doesn't match "
     301                 :             "the size specified in GetSizes(). See documentation for"
     302               0 :             " more information.");
     303                 :     }
     304               0 :     moArray = oArray;
     305               0 :     mbModified = true;
     306               0 : }
     307                 : 
     308                 : /**
     309                 :  * Get the headers of this array. If no headers has be specified, then
     310                 :  * this function return an empty vector.
     311                 :  * the size of this vector should be equal to the size of the first dimension
     312                 :  * returned by GetSize()[0]
     313                 :  *
     314                 :  * @return the headers.
     315                 :  */
     316               0 : const std::vector<std::string>&  CPCIDSK_ARRAY::GetHeaders() const 
     317                 : {
     318               0 :     return moHeaders;
     319                 : }
     320                 : 
     321                 : /**
     322                 :  * Set the headers of this array. An empty vector can be specified to clear
     323                 :  * the headers in the segment.
     324                 :  * the size of this vector should be equal to the size of the first dimension
     325                 :  * returned by GetSize()[0]. If it is not the case, a pci::Exception is thrown.
     326                 :  *
     327                 :  * @param oHeaders the headers.
     328                 :  */
     329               0 : void CPCIDSK_ARRAY::SetHeaders(const std::vector<std::string>& oHeaders) 
     330                 : {
     331               0 :     moHeaders = oHeaders;
     332               0 :     mbModified = true;
     333               0 : }
     334                 : 

Generated by: LCOV version 1.7