LTP GCOV extension - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidskrpcmodel.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 138
Code covered: 0.0 % Executed lines: 0

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CPCIDSKRPCModelSegment class.
       4                 :  * 
       5                 :  ******************************************************************************
       6                 :  * Copyright (c) 2009
       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_rpc.h"
      29                 : #include "segment/cpcidsksegment.h"
      30                 : #include "core/pcidsk_utils.h"
      31                 : #include "pcidsk_exception.h"
      32                 : #include "segment/cpcidskrpcmodel.h"
      33                 : 
      34                 : #include <vector>
      35                 : #include <string>
      36                 : #include <cassert>
      37                 : #include <cstring>
      38                 : 
      39                 : using namespace PCIDSK;
      40                 : 
      41                 : // Struct to store details of the RPC model
      42                 : struct CPCIDSKRPCModelSegment::PCIDSKRPCInfo
      43               0 : {
      44                 :     bool userrpc; // whether or not the RPC was generated from GCPs
      45                 :     bool adjusted; // Whether or not the RPC has been adjusted
      46                 :     int downsample; // Epipolar Downsample factor
      47                 :     
      48                 :     unsigned int pixels; // pixels in the image
      49                 :     unsigned int lines; // lines in the image
      50                 :     
      51                 :     unsigned int num_coeffs; // number of coefficientsg
      52                 :     
      53                 :     std::vector<double> pixel_num; // numerator, pixel direction
      54                 :     std::vector<double> pixel_denom; // denominator, pixel direction
      55                 :     std::vector<double> line_num; // numerator, line direction
      56                 :     std::vector<double> line_denom; // denominator, line direction
      57                 :     
      58                 :     // Scale/offset coefficients in the ground domain
      59                 :     double x_off;
      60                 :     double x_scale;
      61                 :     
      62                 :     double y_off;
      63                 :     double y_scale;
      64                 :     
      65                 :     double z_off;
      66                 :     double z_scale;
      67                 :     
      68                 :     // Scale/offset coefficients in the raster domain
      69                 :     double pix_off;
      70                 :     double pix_scale;
      71                 :     
      72                 :     double line_off;
      73                 :     double line_scale;
      74                 :     
      75                 :     std::vector<double> x_adj; // adjusted X values
      76                 :     std::vector<double> y_adj; // adjusted Y values
      77                 :     
      78                 :     std::string sensor_name; // the name of the sensor
      79                 :     
      80                 :     std::string map_units; // the map units string
      81                 :     
      82                 :     // TODO: Projection Info
      83                 :     
      84                 :     // The raw segment data
      85                 :     PCIDSKBuffer seg_data;
      86                 : };
      87                 : 
      88               0 : CPCIDSKRPCModelSegment::CPCIDSKRPCModelSegment(PCIDSKFile *file, int segment,const char *segment_pointer) :
      89                 :     CPCIDSKSegment(file, segment, segment_pointer), pimpl_(new CPCIDSKRPCModelSegment::PCIDSKRPCInfo), 
      90               0 :     loaded_(false)
      91                 : {
      92               0 :     Load();
      93               0 : }
      94                 : 
      95                 : 
      96               0 : CPCIDSKRPCModelSegment::~CPCIDSKRPCModelSegment()
      97                 : {
      98               0 :     delete pimpl_;
      99               0 : }
     100                 : 
     101                 : // Load the contents of the segment
     102               0 : void CPCIDSKRPCModelSegment::Load()
     103                 : {
     104                 :     // Check if we've already loaded the segment into memory
     105               0 :     if (loaded_) {
     106               0 :         return;
     107                 :     }
     108                 :     
     109               0 :     assert(data_size - 1024 == 7 * 512);
     110                 :     
     111               0 :     pimpl_->seg_data.SetSize(data_size - 1024); // should be 7 * 512
     112                 :     
     113               0 :     ReadFromFile(pimpl_->seg_data.buffer, 0, data_size - 1024);
     114                 :     
     115                 :     // The RPC Model Segment is defined as follows:
     116                 :     // RFMODEL Segment: 7 512-byte blocks
     117                 :     
     118                 :     // Block 1:
     119                 :     // Bytes   0-7: 'RFMODEL '
     120                 :     // Byte      8: User Provided RPC (1: user-provided, 0: computed from GCPs)
     121                 :     // Bytes 22-23: 'DS' 
     122                 :     // Bytes 24-26: Downsample factor used during Epipolar Generation
     123                 :     // Bytes 27-29: '2ND' -- no clue what this means
     124                 :     // Bytes 30-35: 'SENSOR'
     125                 :     // Bytes    36: Sensor Name (NULL terminated)
     126                 :     
     127               0 :     if (std::strncmp(pimpl_->seg_data.buffer, "RFMODEL ", 8)) {
     128                 :         // Something has gone terribly wrong!
     129                 :         throw PCIDSKException("A segment that was previously identified as an RFMODEL "
     130                 :             "segment does not contain the appropriate data. Found: [%s]", 
     131               0 :             std::string(pimpl_->seg_data.buffer, 8).c_str());
     132                 :     }
     133                 :     
     134                 :     // Determine if this is user-provided
     135               0 :     pimpl_->userrpc = pimpl_->seg_data.buffer[8] == 0 ? true : false;
     136                 :     
     137                 :     // Check for the DS characters
     138               0 :     pimpl_->downsample = 1;
     139               0 :     if (!std::strncmp(&pimpl_->seg_data.buffer[22], "DS", 2)) {
     140                 :         // Read the downsample factor
     141               0 :         pimpl_->downsample = pimpl_->seg_data.GetInt(24, 3);
     142                 :     }
     143                 :     
     144                 :     // I don't know what 2ND means yet.
     145                 :     
     146                 :     // Sensor name:
     147               0 :     if (!std::strncmp(&pimpl_->seg_data.buffer[30], "SENSOR", 6)) {
     148               0 :         pimpl_->sensor_name = std::string(&pimpl_->seg_data.buffer[36]);
     149                 :     } else {
     150               0 :         pimpl_->sensor_name = "";
     151                 :     }
     152                 :     
     153                 :     // Block 2:
     154                 :     // Bytes     0-3: Number of coefficients
     155                 :     // Bytes    4-13: Number of pixels
     156                 :     // Bytes   14-23: Number of lines
     157                 :     // Bytes   24-45: Longitude offset
     158                 :     // Bytes   46-67: Longitude scale
     159                 :     // Bytes   68-89: Latitude Offset
     160                 :     // Bytes  90-111: Latitude Scale
     161                 :     // Bytes 112-133: Height offset
     162                 :     // Bytes 134-155: Height scale
     163                 :     // Bytes 156-177: Sample offset
     164                 :     // Bytes 178-199: Sample scale
     165                 :     // Bytes 200-221: Line offset
     166                 :     // Bytes 222-243: line scale
     167                 :     // Bytes 244-375: Adjusted X coefficients (5 * 22 bytes)
     168                 :     // Bytes 376-507: Adjusted Y coefficients (5 * 22 bytes)
     169                 :     
     170               0 :     pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 4);
     171                 :     
     172               0 :     if (pimpl_->num_coeffs * 22 > 512) {
     173                 :         // this segment is malformed. Throw an exception.
     174                 :         throw PCIDSKException("RFMODEL segment coefficient count requires more "
     175                 :             "than one block to store. There is an error in this segment. The "
     176               0 :             "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     177                 :     }
     178                 :     
     179               0 :     pimpl_->lines = pimpl_->seg_data.GetInt(512 + 4, 10);
     180               0 :     pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 14, 10);
     181               0 :     pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 24, 22);
     182               0 :     pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 46, 22);
     183               0 :     pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 68, 22);
     184               0 :     pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 90, 22);
     185               0 :     pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 112, 22);
     186               0 :     pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 134, 22);
     187               0 :     pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 156, 22);
     188               0 :     pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 178, 22);
     189               0 :     pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 200, 22);
     190               0 :     pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 222, 22);
     191                 :     
     192                 :     // Read in adjusted X coefficients
     193               0 :     for (unsigned int i = 0; i <= 5; i++) {
     194               0 :         double tmp = pimpl_->seg_data.GetDouble(512 + 244 + (i * 22), 22);
     195               0 :         pimpl_->x_adj.push_back(tmp);
     196                 :     }
     197                 :     
     198                 :     // Read in adjusted Y coefficients
     199               0 :     for (unsigned int i = 0; i <= 5; i++) {
     200               0 :         double tmp = pimpl_->seg_data.GetDouble(512 + 376 + (i * 22), 22);
     201               0 :         pimpl_->y_adj.push_back(tmp);
     202                 :     }
     203                 :     
     204                 :     // Block 3:
     205                 :     // Block 3 contains the numerator coefficients for the pixel rational polynomial
     206                 :     // Number of Coefficients * 22 bytes
     207               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     208               0 :         pimpl_->pixel_num.push_back(pimpl_->seg_data.GetDouble(2 * 512 + (i * 22), 22));
     209                 :     }
     210                 :     
     211                 :     // Block 4:
     212                 :     // Block 4 contains the denominator coefficients for the pixel rational polynomial
     213                 :     // Number of Coefficients * 22 bytes
     214               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     215               0 :         pimpl_->pixel_denom.push_back(pimpl_->seg_data.GetDouble(3 * 512 + (i * 22), 22));
     216                 :     }
     217                 :     
     218                 :     // Block 5:
     219                 :     // Block 5 contains the numerator coefficients for the line rational polynomial
     220                 :     // Number of Coefficients * 22 bytes
     221               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     222               0 :         pimpl_->line_num.push_back(pimpl_->seg_data.GetDouble(4 * 512 + (i * 22), 22));
     223                 :     }
     224                 :     
     225                 :     // Block 6:
     226                 :     // Block 6 contains the denominator coefficients for the line rational polynomial
     227                 :     // Number of Coefficients * 22 bytes
     228               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     229               0 :         pimpl_->line_denom.push_back(pimpl_->seg_data.GetDouble(5 * 512 + (i * 22), 22));
     230                 :     }
     231                 :     
     232                 :     // Block 7:
     233                 :     // Bytes    0-15: MapUnits string
     234                 :     // Bytes 256-511: ProjInfo_t, serialized
     235               0 :     pimpl_->map_units = std::string(&pimpl_->seg_data.buffer[6 * 512], 16);
     236                 :     
     237                 :     // We've now loaded the structure up with data. Mark it as being loaded 
     238                 :     // properly.
     239               0 :     loaded_ = true;
     240                 :     
     241                 : }
     242                 : 
     243               0 : void CPCIDSKRPCModelSegment::Write(void)
     244                 : {
     245                 :     
     246               0 : }
     247                 : 
     248               0 : std::vector<double> CPCIDSKRPCModelSegment::GetXNumerator(void) const
     249                 : {
     250               0 :     return pimpl_->pixel_num;
     251                 : }
     252                 : 
     253               0 : std::vector<double> CPCIDSKRPCModelSegment::GetXDenominator(void) const
     254                 : {
     255               0 :     return pimpl_->pixel_denom;
     256                 : }
     257                 : 
     258               0 : std::vector<double> CPCIDSKRPCModelSegment::GetYNumerator(void) const
     259                 : {
     260               0 :     return pimpl_->line_num;
     261                 : }
     262                 : 
     263               0 : std::vector<double> CPCIDSKRPCModelSegment::GetYDenominator(void) const
     264                 : {
     265               0 :     return pimpl_->line_denom;
     266                 : }
     267                 : 
     268                 : // Set the RPC Coefficients
     269                 : void CPCIDSKRPCModelSegment::SetCoefficients(
     270                 :     const std::vector<double>& xnum, const std::vector<double>& xdenom,
     271               0 :     const std::vector<double>& ynum, const std::vector<double>& ydenom)
     272                 : {
     273               0 :     if (xnum.size() != xdenom.size() || ynum.size() != ydenom.size() ||
     274                 :         xnum.size() != ynum.size() || xdenom.size() != ydenom.size()) {
     275                 :         throw PCIDSKException("All RPC coefficient vectors must be the "
     276               0 :             "same size.");
     277                 :     }
     278                 :     
     279               0 :     pimpl_->pixel_num = xnum;
     280               0 :     pimpl_->pixel_denom = xdenom;   
     281               0 :     pimpl_->line_num = ynum;
     282               0 :     pimpl_->line_denom = ydenom;
     283               0 : }
     284                 :     
     285                 : // Get the RPC offset/scale Coefficients
     286                 : void CPCIDSKRPCModelSegment::GetRPCTranslationCoeffs(double& xoffset, double& xscale,
     287                 :     double& yoffset, double& yscale, double& zoffset, double& zscale,
     288               0 :     double& pixoffset, double& pixscale, double& lineoffset, double& linescale) const
     289                 : {
     290               0 :     xoffset = pimpl_->x_off;
     291               0 :     xscale = pimpl_->x_scale;
     292                 : 
     293               0 :     yoffset = pimpl_->y_off;
     294               0 :     yscale = pimpl_->y_scale;
     295                 :     
     296               0 :     zoffset = pimpl_->z_off;
     297               0 :     zscale = pimpl_->z_scale;
     298                 :     
     299               0 :     pixoffset = pimpl_->pix_off;
     300               0 :     pixscale = pimpl_->pix_scale;
     301                 :     
     302               0 :     lineoffset = pimpl_->line_off;
     303               0 :     linescale = pimpl_->line_scale;
     304               0 : }
     305                 :     
     306                 : // Set the RPC offset/scale Coefficients
     307                 : void CPCIDSKRPCModelSegment::SetRPCTranslationCoeffs(
     308                 :     const double xoffset, const double xscale,
     309                 :     const double yoffset, const double yscale, 
     310                 :     const double zoffset, const double zscale,
     311                 :     const double pixoffset, const double pixscale, 
     312               0 :     const double lineoffset, const double linescale)
     313                 : {
     314               0 :     pimpl_->x_off = xoffset;
     315               0 :     pimpl_->x_scale = xscale;
     316                 :     
     317               0 :     pimpl_->y_off = yoffset;
     318               0 :     pimpl_->y_scale = yscale;
     319                 : 
     320               0 :     pimpl_->z_off = zoffset;
     321               0 :     pimpl_->z_scale = zscale;
     322                 : 
     323               0 :     pimpl_->pix_off = pixoffset;
     324               0 :     pimpl_->pix_scale = pixscale;
     325                 : 
     326               0 :     pimpl_->line_off = lineoffset;
     327               0 :     pimpl_->line_scale = linescale;
     328                 : 
     329               0 : }
     330                 : 
     331                 : // Get the adjusted X values
     332               0 : std::vector<double> CPCIDSKRPCModelSegment::GetAdjXValues(void) const
     333                 : {
     334               0 :     return pimpl_->x_adj;
     335                 : }
     336                 : 
     337                 : // Get the adjusted Y values
     338               0 : std::vector<double> CPCIDSKRPCModelSegment::GetAdjYValues(void) const
     339                 : {
     340               0 :     return pimpl_->y_adj;
     341                 : }
     342                 : 
     343                 : // Set the adjusted X/Y values
     344                 : void CPCIDSKRPCModelSegment::SetAdjCoordValues(const std::vector<double>& xcoord,
     345               0 :     const std::vector<double>& ycoord)
     346                 : {
     347               0 :     if (xcoord.size() != 6 || ycoord.size() != 6) {
     348                 :         throw PCIDSKException("X and Y adjusted coordinates must have "
     349               0 :             "length 5.");
     350                 :     }
     351                 :     
     352               0 :     pimpl_->x_adj = xcoord;
     353               0 :     pimpl_->y_adj = ycoord;
     354               0 : }
     355                 : 
     356                 : // Get whether or not this is a user-generated RPC model
     357               0 : bool CPCIDSKRPCModelSegment::IsUserGenerated(void) const
     358                 : {
     359               0 :     return pimpl_->userrpc;
     360                 : }
     361                 : 
     362                 : // Set whether or not this is a user-generated RPC model
     363               0 : void CPCIDSKRPCModelSegment::SetUserGenerated(bool usergen)
     364                 : {
     365               0 :     pimpl_->userrpc = usergen;
     366               0 : }
     367                 : 
     368                 : // Get whether the model has been adjusted
     369               0 : bool CPCIDSKRPCModelSegment::IsNominalModel(void) const
     370                 : {
     371               0 :     return !pimpl_->adjusted;
     372                 : }
     373                 : 
     374                 : // Set whether the model has been adjusted
     375               0 : void CPCIDSKRPCModelSegment::SetIsNominalModel(bool nominal)
     376                 : {
     377               0 :     pimpl_->adjusted = !nominal;
     378               0 : }
     379                 : 
     380                 : // Get sensor name
     381               0 : std::string CPCIDSKRPCModelSegment::GetSensorName(void) const
     382                 : {
     383               0 :     return pimpl_->sensor_name;
     384                 : }
     385                 : 
     386                 : // Set sensor name
     387               0 : void CPCIDSKRPCModelSegment::SetSensorName(const std::string& name)
     388                 : {
     389               0 :     pimpl_->sensor_name = name;
     390               0 : }
     391                 : 
     392                 : // Output projection information of RPC Model
     393                 : // Get the Geosys String
     394               0 : std::string CPCIDSKRPCModelSegment::GetGeosysString(void) const
     395                 : {
     396               0 :     return pimpl_->map_units;
     397                 : }
     398                 : 
     399                 : // Set the Geosys string
     400               0 : void CPCIDSKRPCModelSegment::SetGeosysString(const std::string& geosys)
     401                 : {
     402               0 :     if (geosys.size() > 16) {
     403                 :         throw PCIDSKException("GeoSys/MapUnits string must be no more than "
     404               0 :             "16 characters to be valid.");
     405                 :     }
     406               0 :     pimpl_->map_units = geosys;
     407               0 : }
     408                 : 
     409                 : // Get number of lines
     410               0 : unsigned int CPCIDSKRPCModelSegment::GetLines(void) const 
     411                 : {
     412               0 :     return pimpl_->lines;
     413                 : }
     414                 : 
     415               0 : unsigned int CPCIDSKRPCModelSegment::GetPixels(void) const
     416                 : {
     417               0 :     return pimpl_->pixels;
     418                 : }
     419                 : 
     420               0 : void CPCIDSKRPCModelSegment::SetRasterSize(const unsigned int lines, const unsigned int pixels)
     421                 : {
     422               0 :     if (lines == 0 || pixels == 0) {
     423               0 :         throw PCIDSKException("Non-sensical raster dimensions provided: %ux%u", lines, pixels);
     424                 :     }
     425                 :     
     426               0 :     pimpl_->lines = lines;
     427               0 :     pimpl_->pixels = pixels;
     428               0 : }

Generated by: LTP GCOV extension version 1.5