1

I am trying to create a processing chain using C-GDAL. The main() code is as follows:

#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h"
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <sys/stat.h>
#include<stdio.h>
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h"

int const nYSize = 10980, nXSize = 10980;

//Node Structure for Linked-List
struct Node 
{
    char *data;
    struct Node *next;
};

//Declaring global variables
struct Node *B02_list = NULL;
struct Node *SCL_list = NULL;


// Function to replace a string with another 
// string 
char* str_replace(char* string, const char* substr, const char* replacement) {
    char* tok = NULL;
    char* newstr = NULL;
    char* oldstr = NULL;
    int   oldstr_len = 0;
    int   substr_len = 0;
    int   replacement_len = 0;

    newstr = strdup(string);
    substr_len = strlen(substr);
    replacement_len = strlen(replacement);

    if (substr == NULL || replacement == NULL) {
        return newstr;
    }

    while ((tok = strstr(newstr, substr))) {
        oldstr = newstr;
        oldstr_len = strlen(oldstr);
        newstr = (char*)malloc(sizeof(char) * (oldstr_len - substr_len + replacement_len + 1));

        if (newstr == NULL) {
            free(oldstr);
            return NULL;
        }

        memcpy(newstr, oldstr, tok - oldstr);
        memcpy(newstr + (tok - oldstr), replacement, replacement_len);
        memcpy(newstr + (tok - oldstr) + replacement_len, tok + substr_len, oldstr_len - substr_len - (tok - oldstr));
        memset(newstr + oldstr_len - substr_len + replacement_len, 0, 1);

        free(oldstr);
    }

    free(string);

    return newstr;
}


//Function to insert a node into a Linked-List
struct Node *insert(struct Node *Head, char *value)
{
    struct Node *new_string;
    new_string = (struct Node *)malloc(sizeof(struct Node));
    new_string->data = malloc(strlen(value)+1);
    strcpy(new_string->data,value);
    struct Node *temp;
    temp = (struct Node*)malloc(sizeof(struct Node));

    if (Head == NULL)
    {
        temp -> data = new_string->data;
        Head = temp;
        Head -> next = Head;
    }
    else
    {
        temp ->data = new_string->data;
        temp ->next = Head ->next;
        Head -> next = temp;
    }

    return Head;

}


//Function to check if a string finishes with a suffix
int string_ends_with(const char * str, const char * suffix)
{
    int str_len = strlen(str);
    int suffix_len = strlen(suffix);

    return 
        (str_len >= suffix_len) &&
        (0 == strcmp(str + (str_len-suffix_len), suffix));
}


//Function to show the elements of the Linked-List
void show(struct Node *Head)
{
    struct Node *ptr;

    if (Head == NULL)
    {
        printf("List is empty.!");
        return;
    }

    ptr = Head ->next;
    do
    {
        printf("%s\n", ptr->data);
        ptr = ptr->next;
    } while (ptr != Head->next);

}


//Function to find the files in a directory based on a wildcard
struct Node * recurList(char *basePath, char *suffix)
{
    char path[1000];
    struct dirent *dp;

    DIR *dir = opendir(basePath);
    while ((dp = readdir(dir)) != NULL)
    {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
        {
            strcpy(path, basePath);
            strcat(path, "/");
           strcat(path, dp->d_name);

        struct stat s;
            if (stat(path, &s) == 0)
            {
                if( s.st_mode & S_IFDIR )
                {
                recurList(path, suffix);
                }
                else if(s.st_mode &S_IFREG)
                {
                if (string_ends_with(path, suffix))
                    {
                    B02_list = insert(B02_list, path);
                    }
                }
            } 
        }
    }
    return B02_list;
    closedir(dir);
}


//Function to find the SCL files in a directory 
struct Node * recurListSCL(char *basePath, char *suffix)
{
    char path[1000];
    struct dirent *dp;

    DIR *dir = opendir(basePath);
    while ((dp = readdir(dir)) != NULL)
    {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
        {
            strcpy(path, basePath);
            strcat(path, "/");
           strcat(path, dp->d_name);

        struct stat s;
            if (stat(path, &s) == 0)
            {
                if( s.st_mode & S_IFDIR )
                {
                recurListSCL(path, suffix);
                }
                else if(s.st_mode &S_IFREG)
                {
                if (string_ends_with(path, suffix))
                    SCL_list = insert(SCL_list, path);
                }
            } 
        }
    }
    return SCL_list;
    closedir(dir);
}


//Function that counts the number of nodes in a linked-list
int getCount(struct Node* head)
{
    int count = 0;
    struct Node* p;
    p = head ->next;
    do
    {
        printf("%s\n", p->data);
        p = p->next;
        count++;
    } while (p != head->next);

    return count;
}

void *print_arrays(char *band_name)
{
    // to store execution time of code 
    double time_spent = 0.0;
    clock_t begin = clock();
    GDALDatasetH raster;
    GDALAllRegister();
    char *inB               = band_name;
    raster = GDALOpen( inB, GA_ReadOnly);
    if(raster==NULL)
    {
    printf("Invalid Raster Dataset");
    }
    else
    {
    GDALRasterBandH raster_band;
    raster_band = GDALGetRasterBand( raster, 1);
    int nX = GDALGetRasterBandXSize (raster_band);
    printf("%d\n", nX);
    int nY = GDALGetRasterBandYSize (raster_band);
    printf("%d\n", nY);
    int N = nX*nY;
    printf("total N:%d\n", N);
    float *l2= (float *) malloc(sizeof(float)*N);
    int rowcol;
    int value;
    GDALRasterIO(raster_band, GF_Read,0,0,nX,nY,l2,nX,nY,GDT_Float32,0,0);
    // looping through the pixels of this line;
    for(rowcol=0;rowcol<N;rowcol++){
        value = l2[rowcol];
        printf("%d\n", value);
    //    printf(".");
    }
    if(l2 !=NULL) free(l2);
    GDALClose(raster);
    }
    clock_t end = clock();
    time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
    printf("Time elapsed is %f minutes\n", time_spent/60);

    return 0;
}


//Main program
int main()
{
    char path[100];
    char suffix[100];

    printf("Enter path to list files: ");
    scanf("%s", path);
    printf("Enter the wildcard: ");
    scanf("%s", suffix);

    struct Node *B02;
    B02 = NULL;
    struct Node *SCL;
    SCL = NULL;
    B02 = recurList(path, suffix);
    printf("Printing B02_head!\n");
    show(B02);
    char *suffix_scl = "SCL_10m.tif";
    SCL = recurListSCL(path, suffix_scl);
    printf("Printing files in SCL head:\n");
    show(SCL);
    int B02_length = 0;
    int SCL_length = 0;
    B02_length = getCount(B02);
    SCL_length = getCount(SCL);
    printf("BO2 of length: %d\n", B02_length);
    printf("SCL of length: %d\n", SCL_length);

    struct Node* p;
    p = B02 ->next;

    struct Node *s;
    s = SCL ->next;
    int counter = 1;
    int n_imgs;
    n_imgs = B02_length;
    float *l[n_imgs];
    float *scl_l[n_imgs];
    char *out = "B02_avg.tif";
    int nX;

    GDALAllRegister();
    GDALDatasetH hD[n_imgs];
    GDALDatasetH slcD[n_imgs];
    GDALDriverH hDr[n_imgs];
    GDALDriverH sclDr[n_imgs];
    GDALRasterBandH hB[n_imgs];
    GDALRasterBandH sclB[n_imgs];
    for(int i=0; i<n_imgs;i++){
        printf("%s\n", B02->data);
        hD[i] = GDALOpen(B02->data, GA_ReadOnly);
        slcD[i] = GDALOpen(SCL->data, GA_ReadOnly);
        hDr[i] = GDALGetDatasetDriver(hD[i]);
        sclDr[i] = GDALGetDatasetDriver(slcD[i]);
        hB[i] = GDALGetRasterBand(hD[i],1);
        sclB[i] = GDALGetRasterBand(slcD[i],1);
        int nX = GDALGetRasterBandXSize(hB[0]);
        printf("NX IS OF SIZE:\n%d", nX);
        l[i] = (float *) malloc(sizeof(float)*nX);
        scl_l[i] = (float *) malloc(sizeof(float)*nX);
        printf("------------\n");

    }
    int nY = GDALGetRasterBandYSize(hB[0]);
    printf("SIZE OF NY: %d\n", nY);
    // Creating output file
    hD[n_imgs] = GDALCreateCopy(hDr[0], out, hD[0],FALSE,NULL,NULL,NULL);
    hB[n_imgs] = GDALGetRasterBand(hD[n_imgs],1);
    l[n_imgs] = (float *) malloc(sizeof(float)*nX);
    //Accessing the data rowxrow
    for(int row=0;row<=nY;row++){
        for(int i=1;i<n_imgs;i++){
            GDALRasterIO(hB[i],GF_Read,0,row,nX,1,l[i],nX,1,GDT_Float32,0,0);
            //GDALRasterIO(sclB[i], GF_Read,0,row,nX,1,scl_l[i],nX,1,GDT_Float32,0,0);
        }
    }
    return 0;
}

My program fails on the for loop on line 335. I received the following error message:

ERROR 5: T17PLK_20180408T155531_B02_10m.tif, band 1: Access window out of range in RasterIO().  Requested
(0,76) of size 843402319x1 on raster of 10980x10980.
ERROR 5: T17PLK_20180408T155531_B02_10m.tif, band 1: Access window out of range in RasterIO().  Requested
(0,76) of size 843402319x1 on raster of 10980x10980.
ERROR 5: T17PLK_20180408T155531_B02_10m.tif, band 1: Access window out of range in RasterIO().  Requested
(0,76) of size 843402319x1 on raster of 10980x10980.
ERROR 5: T17PLK_20180408T155531_B02_10m.tif, band 1: Access window out of range in RasterIO().  Requested
(0,76) of size 843402319x1 on raster of 10980x10980.
ERROR 5: T17PLK_20180408T155531_B02_10m.tif, band 1: Access window out of range in RasterIO().  Requested
(0,76) of size 843402319x1 on raster of 10980x10980.
More than 1000 errors or warnings have been reported. No more will be reported from now.

I guess it is because I am trying to access some rows outside of the range of 10980 of my raster dataset. I cannot get the source of my error, I think it has to do with this line, when allocating the space for the row of every file:

 l[i] = (float *) malloc(sizeof(float)*nX);

In line 305 I declared the l variable: float *l[n_imgs]; I think this is correct, since I want to allocate space for rows of the same size (10980) for all the raster listed in my linked list B02. However when I iterate over the rasters to read the lines, then the error message appears with a very weird message saying that I am trying to access a window (one dimensional array, from a two dimensional array).

Does anyone have an idea why that occurs?

4
  • 2
    That is way too much code for this forum, please trim it down to the essentials. The error message says you're asking for a very wide chunk of data that exceeds the size of the raster band. On the line GDALRasterIO(hB[i],GF_Read,0,row,nX,1,l[i],nX,1,GDT_Float32,0,0); what is the value of nX if you run it in step debug? I would say it's 843402319. What offset and size were you expecting to get? The raster I/O expects offset (col,row) and size (col,row) which is not the same as your malloc which wants size col * row * sizeof(float) as the amount of data that is to be read. Commented Nov 22, 2019 at 0:42
  • 1
    Is this C or C++? It looks to me more like C++ than ANSI C. There is a big difference between the two and I'm not seeing all the &'s that are common in ANSI C and some ->'s which is valid only in C++ AFAIK. Commented Nov 22, 2019 at 0:50
  • Very helpful. It is ANSI C. And I printed the value of nX Size after line int nY = GDALGetRasterBandYSize(hB[0]); printf("SIZE OF NY: %d\n", nY); it came with very strange values in every iteration. I made a declaration of type nX = GDALGetRasterBandXSize(hB[1]) right after declaring the nY value, and it works now! Thanks for the advices! Commented Nov 22, 2019 at 6:29
  • That's great, can you please answer your own question with the updated code for the changed section. There really aren't many people using ANSI C or C++ GDAL so a working code answer would be quite valuable to those who follow who are finding working examples difficult to find with a google search. Commented Nov 25, 2019 at 0:41

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.