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?
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 typenX = GDALGetRasterBandXSize(hB[1])
right after declaring the nY value, and it works now! Thanks for the advices!