int main(int argc, char** argv) { long nrh, nrl, nch, ncl; byte** I; byte** binary; byte** droits; int theta, roMax, ro; int** tableRT; I = LoadPGM_bmatrix("route0.pgm", &nrl, &nrh, &ncl, &nch); binary = bmatrix(nrl, nrh, ncl, nch); roMax = sqrt(nrh * nrh + nch * nch); tableRT = imatrix(0, 179, 0, roMax); droits = bmatrix(0, 179, 0, roMax); int i, j; for (i = nrl; i < nrh; i++) { for (j = ncl; j < nch; j++) { if (I[i][j] >= 180) binary[i][j] = 255; else binary[i][j] = 0; } } for (theta = 0; theta < 180; theta++) { for (ro = 0; ro < roMax; ro++) { tableRT[theta][ro] = 0; } } for (theta = 0; theta < 180; theta++) { for (i = nrl; i < nrh; i++) { for (j = ncl; j < nch; j++) { if (I[i][j] >= 180) { ro = i * cos(rad(theta)) + j * sin(rad(theta)); tableRT[theta][abs(ro)]++; } } } } int max = 0; for (theta = 0; theta < 180; theta++) { for (ro = 0; ro < roMax; ro++) { if (tableRT[theta][ro] > max) { max = tableRT[theta][ro]; } } } SavePGM_bmatrix(binary, nrl, nrh, ncl, nch, "route_binary.pgm"); free_bmatrix(I, nrl, nrh, ncl, nch); free_bmatrix(binary, nrl, nrh, ncl, nch); return 0; }
int main(int argc, char *argv[]) { struct bildinfo geoinfo; /* alles zum Bildbearbeiten aus dem Header*/ struct bildattribut{ char name[128]; /* Struktur, um fuer jedes Bild die geo- */ int doy; /* zu verarbeiten */ double time; double gamma; double f; double dec; double EOT; double lon_sun; unsigned char headline[HDL]; /* Recordlaenge fuer "echte" Groesse */ short int **imagedata; /* matrix; msg data are assigned to imagedata */ byte **Bimagedata; /* Matrix, mfg data are assigned to Bimagedata */ }; struct bildattribut bildfolge[BILDANZ]; /* Zahl der Listenelemente: Monat = BILDANZ */ int rho_max=0; /* maximale Reflektivitaet bei Met-8 Bildern */ /* Cosinuskorrektur */ double GMT; /* Abscannzeitpunkt */ int quiet=0; /* Bildschirminformationen ? */ int accm; /* parameter for MFG GMT calculation */ int lin, col; /* Zaehlvariablen fuer Zeile und Spalte */ int n=0; /* Anzahl der verarbeiteten Bilder */ int decide; /* ausserhalb der Erde oder nicht */ double lat,lon; /* latitude and longitude in radians ! */ double corr; /* normalisierte Radianz */ double coszen; /* Cosinus des Zenitwinkels */ /* ---> SELFCALIBRATION: declarations */ /* RM May 2008: added file pointer frhomax,fstatrho */ FILE *out_image,*list,*f,*frhomax,*fstatrho; /* RM May 2008: fper and kend1 is needed for the caclulation of the percentile */ short int *fper = NULL; int kend1=0; /* RM May 2008: added averaged angles used for the caclculation of the scatter angle scata */ float msza=0; /* average of the solar zenith angle over time and space within the calibration region */ float mazi=0; /* average of the solar azimuth angle over time and space within the calibration region */ float msatazi=0; /* average of the sat azimuth angle .... */ float msatzen=0; /* average of the satellite zenith angle */ float scata=0; /* the mean scattering angle */ double satazi, satzen; /* geometry of MSG, satellite zenith and azimuth */ float r2d=180.0/3.1416; float esd; /* variable for the geometric correction of rho_max */ float dpos=0.0; /* dpos is the position of Meteosat relativ to lon=0, West is negative, East positive */ /* <--- SELFCALIBRATION declarations */ /* Dateinamen von Bildern */ char out_imagefile[160],groundpathname[128], cloudpathname[128],bild[128],bildpathname[128]; short int **out; /* Matrix fuer die Ausgabewerte */ short int reflectivity_vector[BILDANZ]; short int min, hour; char *cp; /* temporaere Werte */ char zeitname[4]; /* temporaerer ASCII-String der Zeit */ long zahl,anzahl; double cloudindex ; double db_hours_per_line; /* added in order to caclulate the timeoffset */ char *channel="MFGVIS"; /* added, currently hard wired, shoul be provided via heliosat call once the thermal irradiance is included */ short int MFG=1; /* added, currently hard wired, should be provided via heliosat call, once the routine is successfully tested for MFG and MSG !! */ int i,k,laenge; char quite='\0'; short int sig_ground, sig_shadow=0; /* width of distribution of cloudfree pixels and shaded pixels */ /* sig_shadow is zero, the shadow module will not be used, it is too slow and probably not needed if the fuzzy logic Heliosat version is used*/ short int(temp); float doffset=0; /* the dark/space offset of the instrument */ slope=(BYTE_MAX-BYTE_MIN)/(CLOUDI_MAX-CLOUDI_MIN); y_intercept=BYTE_MAX-CLOUDI_MAX*slope; /* DEFINE */ *out_imagefile = '\0'; for(i = 0;i <= BILDANZ;i++){*bildfolge[i].name = '\0';} /*** optionale Argumente von der command line lesen... ***/ if (argc<4) /* wenn nicht mindestens zwei opt.Parameter.. */ exit_print_usage(); /* .. dann schliesse das Programm */ for (i=1; i<argc; i++) /* fuer alle Argumente.. */ { cp=argv[i]; if (*cp!='-' && *cp!='/') /* pruefe ob Argument mit '-' oder '/' beginnt */ { fprintf(stderr,"bodenalbedo: no option specified (%s)\n",cp); exit_print_usage(); } cp++; if (*(cp+1)) /* pruefe ob an uebernaechster Stelle ein Blank */ { fprintf(stderr,"bodenalbedo: missing blank. Usage: -%c <arg>\n",*cp); exit(1); } *cp=(char) tolower((int) *cp); /* es wird nicht zwischen Klein- und * * Grossschreibung unterschieden */ if (*cp=='l') list=fopen(argv[++i],"rt"); else if (*cp=='b') strcpy(bildpathname,argv[++i]); else if (*cp=='c') strcpy(cloudpathname,argv[++i]); else if (*cp=='g') strcpy(groundpathname,argv[++i]); /* ---> SELFCALIBRATION dpos instead of sig_ground !!! */ else if (*cp=='s') dpos=atof(argv[++i]); /*dpos instead of sig_ground, see program header for details */ else if (*cp=='z') MFG=atoi(argv[++i]); /* MFG instead of sig_shadow MFG=1: MFG data expected MFG=0: MSG data */ else if (*cp=='q') quite='q'; else { fprintf(stderr,"bodenalbedo: unknown option: %s\n",cp); exit_print_usage(); } } if (dpos != 0.0) {printf("Meteosat position not at longitude=0 ! Please check -s in the heliosat call & set it to 0 if Met is at lon=0 \n");} if(MFG==1) {printf("assume MFG image data as input !! \n please check if you realy use MFG: -z has to be 0 for MSG \n");} else{ printf("assume MSG image data as input !! \n please check if you realy use MSG: -z has to be 1 for MFG \n"); } /* oeffnen aller Dateien, die in Liste stehen, Header auswerten, Matrizen zuweisen */ zahl=0; while(!feof(list) && anzahl < BILDANZ ) /* CaP - inserting the limit of BILDANZ to avoid coredumps*/ /* || anzahl < BILDANZ ) */ { anzahl=zahl; fscanf(list,"%s\r",bildfolge[anzahl].name); strcpy(bild,bildpathname); strcat(bild,"/"); strcat(bild,bildfolge[anzahl].name); if(!quite)printf("%d %s\n",anzahl,bild); read_xpif_header(HDL,bild,&bildfolge[anzahl].headline[0]); /* store header for output XPIF-images */ if(HDL==256) { bildfolge[anzahl].headline[11]=(unsigned char) 0; /* no additional headers wanted ! */ } if (MFG==1) { bildfolge[anzahl].Bimagedata=read_xpif_to_Bmatrix(HDL,bild,&geoinfo); bildfolge[anzahl].imagedata=smatrix(0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); /* RM 17.07.09: dark offset and snanning time is different for MFG and MSG */ db_hours_per_line=(25./geoinfo.nrlines/60.); doffset=4.5*4; for (lin = 0;lin < geoinfo.nrlines;lin++) { /* change type and rotate the image, afterwards free bmatrix */ for(col = 0;col < geoinfo.nrcolumns;col++){ /* temp=(short int)bildfolge[anzahl].Bimagedata[geoinfo.nrlines-lin-1][geoinfo.nrcolumns-col-1]; */ /* correct if old openMTP converter is used */ bildfolge[anzahl].imagedata[lin][col]=4*(short int)bildfolge[anzahl].Bimagedata[geoinfo.nrlines-lin-1][geoinfo.nrcolumns-col-1]; /* correct if new openMTP to XPIF converter is used */ /* bildfolge[anzahl].imagedata[lin][col]=4*(short int)bildfolge[anzahl].Bimagedata[lin][col]; */ /* multiplication with factor 4 needed in order to have only one BYTE MAX definition */ /* (short int)bildfolge[anzahl].Bimagedata[lin][col]; */ /* (short int)bildfolge[anzahl].Bimagedata[geoinfo.nrlines-lin-1][geoinfo.nrcolumns-col-1]; */ /* printf("i,j,temp= %d %d %d",lin, col, temp); */ } } free_bmatrix(bildfolge[anzahl].Bimagedata,0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); /* bildfolge[anzahl].Bimagedata=read_xpif_to_Bmatrix(HDL,bild,&geoinfo); */ } else{ bildfolge[anzahl].imagedata=read_xpif_to_matrix(HDL,bild,&geoinfo); db_hours_per_line=(12./geoinfo.nrlines/60.); doffset=51; } printf("Iam here 1 %d %d \n",geoinfo.nrlines, geoinfo.nrcolumns); bildfolge[anzahl].doy=geoinfo.doy; hour=geoinfo.aq_time /100; min=fmod(geoinfo.aq_time,100); bildfolge[anzahl].time=hour+min/60.0; bildfolge[anzahl].EOT=equation_of_time(bildfolge[anzahl].doy,&bildfolge[anzahl].gamma,&bildfolge[anzahl].f,&bildfolge[anzahl].dec); zahl++; } n=anzahl; printf ("n= %d \n",n); /* printf("doy is %04d %04d \n",geoinfo.doy, geoinfo.aq_time ); printf("nrs is %d %d %d %d \n",geoinfo.nrlines,geoinfo.nrcolbig,geoinfo.nrcolumns, geoinfo.nrlines ); printf("nrs is %d %d %d %d \n",geoinfo.line_off,geoinfo.col_off,geoinfo.nav_lres, geoinfo.nav_cres ); */ /* orig out=smatrix(0,geoinfo.nrlines-1,0,geoinfo.nrcolbig-1); RM 24.02->*/ out=smatrix(0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); /*** Normalize images ---------------------------------------- ***/ /* allocate memory for fper 42610*/ /* fper = malloc(45000 * (n+1) * sizeof(short int)); if(fper == NULL) { fprintf(stderr, "not enough memory for array fper, needed for automatic calibration \n"); exit; } */ /* CaP - allocating only 2 bytes for now. Using realloc later in the loop below (line 719). The former memory allocation (previous line) causes severe memory errors and program crashes */ /* --> SELFCALIBRATION: initial allocation of field needed for the percentiles */ fper = malloc(sizeof(short int)); /* <-- */ printf("Iam here 2 \n"); accm=0; for (lin = 0;lin < geoinfo.nrlines;lin++) /* fuer alle Zeilen */ { /* 12.10.09 included new lines for the calculation of GMT. Now MFG and MSg can be processed */ /* old, orig for MSG GMT=bildfolge[anzahl].time+timeoffset(geoinfo.nav_lres,geoinfo.line_off,lin,15); */ /* GMT : Abscannzeitpunkt dieser Zeile bestimmen */ /* 17.07.09 fixed GMT bug, accm needed to consider that two subsequent lines are scanned in || */ accm=accm+abs((lin-1)%2); GMT=bildfolge[anzahl].time+(double)lin*db_hours_per_line; /* printf("now here vv \n");*/ if ((strcmp(channel,"MFGVIS")==0) && MFG==1) { /* CaP 29.04.2009 - in the vis imagery adjacent lines are scanned in couples */ GMT=bildfolge[anzahl].time+(double)(accm-1)*db_hours_per_line; /* printf("GMT,accm= %f %d \n",GMT ,accm); */ } /* orig GMT=bildfolge[anzahl].time+timeoffset(geoinfo.nav_lres,geoinfo.line_off,lin,15); */ /* GMT=bildfolge[anzahl].time+timeoffset(geoinfo.nav_lres,geoinfo.line_off,lin,15); */ for (k = 0 ;k <= n;k++) /* fuer alle Bilder */ { /* fuer Abscannzeit dieser Zeile und jeden Tag den Sonnenstand bestimmen */ bildfolge[k].lon_sun=(12.0-GMT-(bildfolge[k].EOT/60.0))*15*(PI/180.0); } /* printf("ere re re %d \n",k); */ for(col = 0;col < geoinfo.nrcolumns;col++) /* fuer alle Spalten */ { if(MFG==1){ decide=geoloc(lin,col,geoinfo.nrlines,&lat,&lon); } else{ decide=geomsg(geoinfo.nav_cres,geoinfo.nav_lres,geoinfo.col_off,geoinfo.line_off,lin,col,&lat,&lon); } /* if (decide == 0){ printf("the geoloc i,j,lat,lon %d %d %f %f \n", lin, col,lat*180/pi,lon*180/pi); } */ /* orig decide=geomsg(geoinfo.nav_cres,geoinfo.nav_lres,geoinfo.col_off,geoinfo.line_off,lin,col,&lat,&lon); */ /* ---> SELFCALIBRATION: calculation of additional angles */ /* RM Jul 2008: added equations for the calculation of satellite zenith and azimuth !! it is assumed that the satellite is at lat=lon=0 h=42164.0 height of geostationary Satellite */ satazi = atan(sin(lon-dpos/r2d)/tan(lat)); /* rm 072008 modified formular, covers all positions of Meteosat now */ /* old satzen = fabs(atan(sin(lat) * h/(cos(lat) * h - R_E))); */ satzen=90/r2d-atan((cos(dpos/r2d-lon)*cos(lat)-0.1512)/sqrt(1-pow(cos(dpos/r2d-lon),2)*pow(cos(lat),2))); /* <--- SELFCALIBRATION: calculation of additional angles */ if (decide==0) { for(k = 0 ;k <= n;k++) /* fuer alle Bilder */ { corr=0; coszen=cos_zenit(lat,lon,bildfolge[k].dec,bildfolge[k].lon_sun); if(coszen>0.02) corr = (int)((bildfolge[k].imagedata[lin][col]-doffset)/coszen); /* orig 51 instead of doffset */ corr = mini(corr,BYTE_MAX); corr = maxi(corr,BYTE_MIN); bildfolge[k].imagedata[lin][col] = corr; /* RM 20.11.07: automatic calculation of rho_max starts, sort vector content according to the value, in ascending order using heapsort, Numerical Recipies in C the 95 percentil * 1.1 is than the desired rhomax value */ /* ---> SELFCALIBRATION: Calculate the percentile and additional angles needed for the calculation of the scatter angle */ if(lat > -0.92 && lat < -0.8 && lon < (-0.01 + dpos/r2d) && lon > (-0.262+dpos/r2d)) /* -0.436*/ /* RM 072008: added +dpos in order to shift the reference region for Meteosat-East dpos=position of Meteosat relative to lon=0 in degree, west is negative */ { fper[kend1]=(short int)bildfolge[k].imagedata[lin][col]; /* assign values within region to fper */ kend1=kend1+1; /* calculate the mean angles as basis for the caclulation of the scatter angle, needed for the geometric correction of rhomax */ fper = realloc(fper,(kend1+1)*sizeof(short int)); msza=((kend1-1)*msza+acos(coszen))/kend1; mazi=((kend1-1)*mazi+azimuth(lat,lon,bildfolge[k].dec,acos(coszen),bildfolge[k].lon_sun))/kend1; msatazi=((kend1-1)*msatazi+satazi)/kend1; msatzen=((kend1-1)*msatzen+satzen)/kend1; } /* <--- end of SELFCALIBRATION: Calculate the percentile and additional angles needed for the calculation of the scatter angle */ } } if (decide==1){ out[lin][col] = (int) 0; for(k=1;k<=n;k++){ /* if(geoinfo.nrlines<200){doffset=doffset+ bildfolge[15].imagedata[lin][col];} */ bildfolge[k].imagedata[lin][col] = 0; } } } } printf("doffset= %f \n", doffset); printf("now I am here \n"); /* ---> SELFCALIBRATION: sorting the fper field and assignment of the percentiles */ heapsort(kend1, fper); /* order the counts */ int p1=(int)(0.1*(kend1+1)); int p3=(int)(0.3*(kend1+1)); int p5=(int)(0.5*(kend1+1)); int p7=(int)(0.7*(kend1+1)); int p8=(int)(0.8*(kend1+1)); int p9=(int)(0.9*(kend1+1)); int pm=(int)(0.95*(kend1+1)); /* <--- SELFCALIBRATION: sorting the fper field and assignment of the percentiles */ /* ---> SELFCALIBRATION: empirical correction of anisotropy for rho_max */ /* RM 28.05.08 empirical correction for scatter angle effect, so far formula only proven for 3 - 33 degree, RM 30.07.08 implemented new formula, correction works from 3-70 degree (scata), but probably only for the reference regions and not everywhere, above scattering angle of 32 the uncertainty of the geometric corrections is significnat higher */ scata=scatt_angle(msza, mazi, msatzen, msatazi); /* added new correction for rho_max, seems that the dominant effect comes from the sza dependent change of the cloud albedo, the clouds seems to reflect pretty well isotropic for a given SZA and rel AZA lower than 60 degree the correction formula results from a linear fit (gnuplot) applied to a 2.5 year time series for all slots with SZA>60 */ if (msza*r2d > 80.0 && msza*r2d <0.0) esd=1.0; /* gcor =1 for SZA>80 and <0*/ else {esd=1+0.0017*(45.0-msza*r2d); } /* <--- SELFCALIBRATION: empirical correction of anisotropic cloud reflection for rho_max */ /* ---> SELFCALIBRATION: Open and write the output files for information related to the self calibration approach */ fstatrho=fopen("rhostat.out","a") ; fprintf(fstatrho, "# kend1= %d doy= %d hour= %d min = %d \n",kend1,geoinfo.doy, hour,min); fprintf(fstatrho, " gcor= %f msza= %f mazi= %f satazi= %f satzen= %f scattangle= %f rhomax %f pm= %d \n", esd, msza*r2d, (mazi)*r2d, msatazi*r2d, msatzen*r2d, scata*r2d, fper[pm]*esd*1.1, fper[pm]); fprintf(fstatrho, "# ESD= %f rho(10,30,50,70,80,90,95)= %d %d %d %d %d %d %d rhomax %f \n",esd,fper[p1],fper[p3],fper[p5],fper[p7], fper[p8],fper[p9],fper[pm], fper[pm]*esd*1.1); if (hour==13 && min==0) { frhomax=fopen("rhomax.out","w"); /* RM 072008 changed r+ to w, r+ does not work properly on my machine */ rho_max=fper[pm]*esd*1.1; fprintf(frhomax, "%d \n", rho_max); fprintf(fstatrho,"## The noon rho_may is %d \n",rho_max ); fclose(frhomax); } else { /* if((frhomax=fopen("rhomax.out","r")) == NULL) */ if(file_exists("rhomax.out")) { frhomax=fopen("rhomax.out","r"); fscanf(frhomax, "%d", &rho_max); fprintf(fstatrho,"# Use noon rhomax from rhomax.out %d \n",rho_max ); printf("Use noon rhomax from rhomax,out %d \n",rho_max ); fclose(frhomax); } else { fprintf(fstatrho,"# WARNING Cannot open rhomax file, hence instead of the noon rhomax that of the actual slot is used,which might lead to higher uncertainty.\n"); rho_max=(int)fper[pm]*esd*1.1; fprintf(fstatrho,"# Use rhomax of actual slot %d \n",rho_max ); /*fclose(frhomax);*/ } } sig_ground=(short int)(0.035 * rho_max); fprintf(fstatrho,"# sig_ground =%d \n \n",sig_ground ); fclose(fstatrho); free(fper); /* <--- SELFCALIBRATION: Open and write the output files for information related to the self calibration approach */ printf("Finished normalizing images and automatic calibration \n"); /* * Grundalbedo and Cloud Index ---------------------------------------- */ for (lin = 0;lin < geoinfo.nrlines;lin++) /* fuer alle Pixel (Zeilen ... */ { for(col = 0; col < geoinfo.nrcolumns; col++) /* ... und Spalten) */ { for(k = 0; k<=n; k++) { /* copy all values to a vector, from these values ground albedo will de determined reflectivity_vector contains all reflectivity values for one location */ reflectivity_vector[k]=bildfolge[k].imagedata[lin][col]/bildfolge[k].f; /* /f correct for earth sun-distance **/ } /* calculation of ground albedo: out[lin][col]contains ground albedo reflectivity_vector contains cloud index values */ out[lin][col]=groundreflectivity_and_cloudindex(&reflectivity_vector[0], n, sig_ground, sig_shadow, rho_max); for(k = 0; k<=n; k++) { /* copy all cloud index values from vector back to matrix */ bildfolge[k].imagedata[lin][col]=reflectivity_vector[k]; } } } /*********************************************************************** * Ausgeben aller Bilder und Freisetzung des Speicherplatzes... ***********************************************************************/ /* Bodenalbedonamen zusammensetzen */ /* RM changed the naming of the reflectance files, mothly means for every slot are calculated and has to be saved, with the old naming they are overriden */ strcpy(out_imagefile,groundpathname); strcat(out_imagefile,"/"); sprintf(zeitname,"%04d",geoinfo.aq_time); strncat(out_imagefile,bildfolge[1].name,6); /* added string for year and month */ /*strncat(out_imagefile,zeitname,4);*/ strcat(out_imagefile,zeitname); /* printf("out_imagefile = %s bildfolge.name= %s\n",out_imagefile, bildfolge[1].name); */ if(HDL==256)strcat(out_imagefile,"hhmm.REF"); if(HDL==260)strcat(out_imagefile,"hhmm.REF.X260"); /* Grundalbedo speichern */ printf("nrbytes= %d",geoinfo.nrbytes) ; if (!(out_image=fopen(out_imagefile,"wb"))) exit_no_write(out_imagefile); if (MFG==1) {geoinfo.nrbytes=geoinfo.nrbytes*2;} /* dangerous, only for testing */ fwrite(&bildfolge[1].headline[0],HDL,1,out_image); /* orig fwrite(&out[0][0],geoinfo.nrcolbig*geoinfo.nrlines*(long)geoinfo.nrbytes,1,out_image); fclose(out_image); free_smatrix(out,0,geoinfo.nrlines-1,0,geoinfo.nrcolbig-1); */ fwrite(&out[0][0],geoinfo.nrcolumns*geoinfo.nrlines*(long)geoinfo.nrbytes,1,out_image); fclose(out_image); free_smatrix(out,0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); for(k=0;k<=n;k++) { strcpy(out_imagefile,cloudpathname); strcat(out_imagefile,"/"); strncat(out_imagefile,bildfolge[k].name,strlen(bildfolge[k].name)-4); if(HDL==256)strcat(out_imagefile,"CI.XPIF"); if(HDL==260)strcat(out_imagefile,"CI.X260"); if (!(out_image=fopen(out_imagefile,"wb"))) exit_no_write(out_imagefile); fwrite(&bildfolge[k].headline[0],HDL,1,out_image); /* orig fwrite(&bildfolge[k].imagedata[0][0],geoinfo.nrcolbig*geoinfo.nrlines*(long)geoinfo.nrbytes,1,out_image); */ /* memcpy(void *dest, const void *src, size_t n);*/ bildfolge[k].Bimagedata=bmatrix(0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); for (lin = 0;lin < geoinfo.nrlines;lin++) { for(col = 0;col < geoinfo.nrcolumns;col++){ bildfolge[k].Bimagedata[lin][col]=(byte)(bildfolge[k].imagedata[lin][col]/4); } } fwrite(&bildfolge[k].Bimagedata[0][0],geoinfo.nrcolumns*geoinfo.nrlines,1,out_image); free_bmatrix(bildfolge[k].Bimagedata,0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); fclose(out_image); free_smatrix(bildfolge[k].imagedata,0,geoinfo.nrlines-1,0,geoinfo.nrcolumns-1); /* orig geoinfo.nrcolbig-1 */ } return(0); }