Opened 11 years ago

Closed 11 years ago

#5151 closed defect (invalid)

Segmentation fault when calling SetGCPs for VRTDataset

Reported by: zsears Owned by: warmerdam
Priority: highest Milestone:
Component: default Version: svn-trunk
Severity: blocker Keywords: Segmentation Fault
Cc: zsears

Description

Hello,

I am attempting to take add ground control points to a VRTDataset, but for some reason whenever I call the SetGCPs method GDAL has a segmentation fault that I can’t seem to track down. Basically what I am trying to do is take a satellite raster image, so no projection, and transform that into a web mercator projection(EPSG:3857). I am pretty sure that I have done everything correct according to the API, but won’t go so far as to guarentee it. A sample bit of code is below:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include "gdalwarper.h"
#include "gdal_priv.h"
#include "vrtdataset.h"
#include "gdal_vrt.h"
#include "cpl_string.h"
#include <unistd.h>
#include <stdint.h>
#include <gdal.h>

using namespace std;
using std::ostringstream;

int main(int argc, char *argv[]){

    int i,j;
    char *pszSourceFileName = NULL;
    GDAL_GCP *gcps = NULL;
    GDALDatasetH hDstDS;
    VRTDataset *hSrcDS;
    GDALWarpOptions *psWarpOptions;
    GDALWarpOperation *oOperation;
    GDALDriver *poDriver;
    
    string imgFile;
    string gcpFile;
    string outFile;
    vector<string> gcpX, gcpY, gcpZ;
    int polyOrder;
    
    // Deal with the command line
    int c;
    while (( c = getopt(argc,argv,"f:g:o:p:")) != EOF){
      switch(c){
        case 'f':
          imgFile = optarg;
          cout << imgFile << endl;
          break;
        case 'g':
          gcpFile = optarg;
          cout << gcpFile << endl;
          break;
        case 'o':
          outFile = optarg;
          cout << outFile << endl;
          break;
        case 'p':
          polyOrder = atoi(optarg);
          cout << polyOrder << endl;
          break;
      }
    }
    
    // Read in the gcp file
    ifstream gcpFid (gcpFile.c_str(),ifstream::in);
    
    // Read in a line at a time
    string line;
    string token;
    vector<float> row,col;
    vector<float> lat,lon,el;
    int count,offset;
    string delimiter = " ";
    while (getline(gcpFid,line)){
      
      // Parse out the line
      count = 0;
      while ((offset = line.find(delimiter)) != string::npos){
        token = line.substr(0,offset);
        line.erase(0, offset + delimiter.length());
        
        // Put the token in the correct vector, the format of the file line is
        // COL ROW LON LAT
        if ( count == 0 ){
          col.push_back(atof(token.c_str()));
        }
        else if ( count == 1 ){
          row.push_back(atof(token.c_str()));
        }
        else if ( count == 2 ){
          lon.push_back(atof(token.c_str()));
        }
        else if ( count == 3 ){
          lat.push_back(atof(token.c_str()));
        }
        else
          cout << "SHIT how did we get here:    " << token.c_str() << endl;
        
        token.clear();
        count++;
      }
    }
    
    gcpFid.close();
    // Put the points into the gcps
    gcps = (GDAL_GCP *) CPLRealloc (gcps, (col.size()) * sizeof(GDAL_GCP));
    GDALInitGCPs(1, gcps + col.size() - 1);
    for (i = 0; i < col.size(); i++){
      gcps[i].dfGCPPixel = col[i];
      gcps[i].dfGCPLine = row[i];
      gcps[i].dfGCPX = lon[i];
      gcps[i].dfGCPY = lat[i];
      gcps[i].dfGCPZ = (float) 0.0;
    }
    
    // Read in the img file
    ifstream imgFid (imgFile.c_str(),ifstream::in);
    int32_t img[1024*1024] = {0};
    int rowIndx = 0;
    count = 0;
    while (getline(imgFid,line)){
      // Parse out the line
      while ((offset = line.find(delimiter)) != string::npos){
        token = line.substr(0, offset);
        line.erase(0,offset + delimiter.length());
        
        img[count] = (int32_t) atoi(token.c_str());
        count++;
      }
      
      rowIndx++;
    }
    
    // Register all drivers
    GDALAllRegister();
    
    char** papszOptions = NULL;
    hSrcDS = new VRTDataset(1024,1024);
    
    hSrcDS->AddBand(GDT_Int32,papszOptions);
    
    cout << "Number of GCP's:    " << ((int) col.size()) << endl;  // Is zero at this point
    const char *projection = "+proj=latlong +datum=WGS84";
    hSrcDS->SetGCPs(121,gcps,projection);                          // SEGMENTATION FAULT IS HERE
    cout << "DONE" << endl;

Change History (1)

comment:1 by Even Rouault, 11 years ago

Resolution: invalid
Status: newclosed

I believe the error is : GDALInitGCPs(1, gcps + col.size() - 1); which only inits the last GCP So there are string pointers that are likely pointing to any random location in your code.

It should be GDALInitGCPs(col.size(), gcps) so that all GCPs are properly initialized.

In hSrcDS->SetGCPs(121,gcps,projection);, I also assume that 121 == col.size()

Closing this as I believe the issue is in your code and not in GDAL. Reopen if you believe not.

Note: See TracTickets for help on using tickets.