/* output.c */ /* * Vis5D system for visualizing five dimensional gridded data sets. * Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul, * Dave Santek, and Andre Battaiola. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * As a special exception to the terms of the GNU General Public * License, you are permitted to link Vis5D with (and distribute the * resulting source and executables) the LUI library (copyright by * Stellar Computer Inc. and licensed for distribution with Vis5D), * the McIDAS library, and/or the NetCDF library, where those * libraries are governed by the terms of their own licenses. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "../config.h" /* * Make the output file. */ #include #include #include #include #include "analyze_i.h" #include "file_i.h" #include "grid_i.h" #include "memory.h" #include "misc_i.h" #include "proj_i.h" #include "projlist_i.h" #include "resample_i.h" #include "api.h" #include "v5d.h" #include "gui.h" extern int Debug_i; /* * Write a grid of missing values. * Input: v5d - the v5d file handle * time, var - which timestep and variable * nr, nc, nl - size of 3-D grid */ static void write_missing_grid( v5dstruct *v5d, int time, int var, int nr, int nc, int nl ) { static float *missing = NULL; static int gridsize = 0; int i; if (nr*nc*nl > gridsize) { /* allocate and initialize a larger grid of missing values */ if (missing) FREE(missing, 1); gridsize = nr*nc*nl; missing = (float *) MALLOC( gridsize * sizeof(float) ); for (i=0;i0) { result[i] = sum / (float) count; } else { result[i] = MISSING; } } } /* * Like above but don't average, use first non-MISSING value. */ void merge_values( int numvalues, int numgrids, float *grids[], float *result ) { int i, j; for (i=0;iProj > glist[j]->Proj) { swap = 1; } else if (glist[i]->Proj == glist[j]->Proj) { /* compare Vcs pointers */ if (glist[i]->Vcs > glist[j]->Vcs) { swap = 1; } else if (glist[i]->Vcs == glist[j]->Vcs) { /* compare grid rows */ if (glist[i]->Nr < glist[j]->Nr) { swap = 1; } else if (glist[i]->Nr == glist[j]->Nr) { /* compare grid columns */ if (glist[i]->Nc < glist[j]->Nc) { swap = 1; } } } } if (swap) { struct grid_info *gtemp = glist[i]; glist[i] = glist[j]; glist[j] = gtemp; } } } } #endif /* * Combine a number of 2-D grids with the same map projection to form a * 3-D grid. */ static float *combine_2d_grids( struct grid_db *db, int numgrids, struct grid_info *glist[], struct projection **proj, struct vcs **vcs ) { float *height; int i, j, n, m; int nr, nc, nl; float *grid; int equally_spaced; assert( numgrids>1 ); height = (float *) MALLOC( numgrids * sizeof(float) ); #ifdef LEAVEOUT /* Determine how many grids to combine */ for (i=0; iProj==glist[0]->Proj && glist[i]->Vcs->Nl==1) { height[i] = glist[i]->Vcs->Args[0]; } else { break; } } n = i; #else for (i=0; iVcs->Nl == 1 ); height[i] = glist[i]->Vcs->Args[0]; } n = numgrids; #endif /* we now have an array of [n] height values for the 2-D grids to combine */ /* sort 2-D grids by height coordinate */ for (i=0;iheight[j]) { /* swap */ float htemp; struct grid_info *gtemp; htemp = height[i]; height[i] = height[j]; height[j] = htemp; gtemp = glist[i]; glist[i] = glist[j]; glist[j] = gtemp; } } } /* remove duplicate heights, which is possible */ m = 0; for (i=0;iVcs->Kind==VERT_GENERIC) { *vcs = new_vcs( db, VERT_GENERIC, n, 0, args ); } else { *vcs = new_vcs( db, VERT_EQUAL_KM, n, 0, args ); } } else { *vcs = new_vcs( db, VERT_UNEQUAL_KM, n, 0, height ); } *proj = glist[0]->Proj; assert(*vcs); assert(*proj); /* all done with array of grid heights */ FREE(height, 2); /* Allocate storage for the 3-D grid */ nr = glist[0]->Proj->Nr; nc = glist[0]->Proj->Nc; nl = n; grid = (float *) MALLOC( nr * nc * nl * sizeof(float) ); if (!grid) { return NULL; } /* build the 3-D grid */ for (i=0;iMatrix[time][var]; numgrids = 0; while (g && numgridsSelectBits==ALL_BITS) { glist[numgrids] = g; numgrids++; } g = g->Sibling; } if (numgrids>=MAX_GRIDS) { } if (numgrids==0) { /* Either no data present or it's not selected for output */ *proj = NULL; *vcs = NULL; return NULL; } else if (numgrids==1) { /* Common, simple case */ *proj = glist[0]->Proj; *vcs = glist[0]->Vcs; return get_file_data( glist[0] ); } else { /* multiple grids! */ sort_similar_grids( numgrids, glist ); if (glist[0]->Vcs->Nl > 1) { /* just use the first 3-D grid in the list */ *proj = glist[0]->Proj; *vcs = glist[0]->Vcs; return get_file_data( glist[0] ); } else { return combine_2d_grids( db, numgrids, glist, proj, vcs ); } } #undef MAX_GRIDS } #endif #ifdef LEAVEOUT /* * Return a pointer to the 3-D grid of data resampled to the output file's * map projection and VCS. * Input: db - the grid data base * time, vvar - which timestep and variable * outproj - output projection * outvcs - output VCS * outnl - number of grid levels wanted * Return: pointer to 3-D grid of values which may be free()'d or * NULL if there's no grid data */ static float *get_resampled_data( struct grid_db *db, int time, int var, struct projection *outproj, struct vcs *outvcs, int outnl ) { float *outdata; struct projection *gridproj; struct vcs *gridvcs; struct resampler *resamp; assert( outnl <= outvcs->Nl ); /* get grid data in its original size, projection and VCS */ outdata = get_grid_data( db, time, var, &gridproj, &gridvcs ); if (!outdata) { return NULL; } resamp = get_resampler( gridproj, gridvcs, outproj, outvcs, outnl ); if (Debug_i) { printf("Input grid: "); print_min_max( outdata, gridproj->Nr * gridproj->Nc * gridvcs->Nl ); } /* do vertical resampling if needed */ if (gridvcs!=outvcs) { float *indata = outdata; outdata = (float *) MALLOC( gridproj->Nr * gridproj->Nc * outnl * sizeof(float) ); resample_vertical( resamp, indata, outdata ); FREE( indata, 4 ); } if (Debug_i) { printf("After vert resamp: "); print_min_max( outdata, gridproj->Nr * gridproj->Nc * outnl ); } /* do horizontal resampling if needed */ if (gridproj!=outproj) { float *indata = outdata; outdata = (float *) MALLOC( outproj->Nr * outproj->Nc * outnl * sizeof(float) ); resample_horizontal( resamp, indata, outdata ); FREE( indata, 5 ); } if (Debug_i) { printf("After horiz resamp: "); print_min_max( outdata, outproj->Nr * outproj->Nc * outnl ); } return outdata; } #endif /* * Given a list of grids, combine all sets of 2-D grids with same map * projection into new 3-D grids. Return the new list of grids. * Input: db - the grid data base * In/Out: numgrids - how many grids in the list * glist - list of grids * * Example: suppose we have a list of 6 input grids: * 1. 6 levels * 2. 1 level, map projection #4 * 3. 1 level, map projection #4 * 4. 1 level, map projection #5 * 5. 6 levels * 6. 1 level, map projection #4 * * The list of output grids would be: * 1. 6 levels * 2. 3 levels, map projection #4 (1,2 and 6 stacked) * 3. 1 level, map projection #5 * 4. 6 levels */ static void find_and_combine_2d_grids( struct grid_db *db, int *numgrids, struct grid_info *glist[] ) { struct grid_info *outlist[100]; int numout; int i, j; numout = 0; for (i=0;i<*numgrids;i++) { if (glist[i]) { if (glist[i]->Vcs->Nl==1) { struct grid_info *gp[100]; /* grids with same projection */ int ngp; /* how many in gp[] array */ struct grid_info *newgrid; /* the "stacked" gp[] grids */ /* make a list of containing this 2-D grid and all others with */ /* the same horizonal coordinate system */ gp[0] = glist[i]; ngp = 1; for (j=i+1;j<*numgrids;j++) { if (glist[j] && glist[j]->Vcs->Nl==1 && glist[j]->Proj==glist[i]->Proj) { gp[ngp++] = glist[j]; glist[j] = NULL; /* remove */ } } glist[i] = NULL; /* remove */ /* Construct a new grid_info from a stack of 2-D grids */ newgrid = alloc_grid_info(); newgrid->TimeStep=123; newgrid->Data = combine_2d_grids( db, ngp, gp, &newgrid->Proj, &newgrid->Vcs ); assert(newgrid->TimeStep==123); assert(newgrid->Proj); assert(newgrid->Vcs); newgrid->Nr = newgrid->Proj->Nr; newgrid->Nc = newgrid->Proj->Nc; newgrid->Nl = newgrid->Vcs->Nl; /* add new grid to output list */ outlist[numout++] = newgrid; } else { /* just add this grid to the output list */ outlist[numout++] = glist[i]; } } } /* Return output grid list */ for (i=0;iNl!=outnl) { printf("**** outvcs->Nl != outnl in get_r_3_d\n"); } assert( g ); assert( g->Nl==g->Vcs->Nl ); /* get grid data in its original size, projection and VCS */ if (g->Data) { /* Return a copy of grid data unchanged */ outdata = MALLOC( g->Nr * g->Nc * g->Nl * sizeof(float) ); if (!outdata) { return NULL; } memcpy( outdata, g->Data, g->Nr * g->Nc * g->Nl * sizeof(float) ); } else { outdata = get_file_data( g ); if (!outdata) { return NULL; } } resamp = get_resampler( g->Proj, g->Vcs, outproj, outvcs, outnl ); if (Debug_i) { printf("Input grid: "); print_min_max( outdata, g->Proj->Nr * g->Proj->Nc * g->Vcs->Nl ); } /* do vertical resampling if needed */ if (g->Vcs!=outvcs) { float *indata = outdata; outdata = (float *) MALLOC( g->Proj->Nr * g->Proj->Nc * outnl * sizeof(float) ); resample_vertical( resamp, indata, outdata ); FREE( indata, 6 ); } if (Debug_i) { printf("After vert resamp: "); print_min_max( outdata, g->Proj->Nr * g->Proj->Nc * outnl ); } /* do horizontal resampling if needed */ if (g->Proj!=outproj) { float *indata = outdata; outdata = (float *) MALLOC( outproj->Nr * outproj->Nc * outnl * sizeof(float) ); resample_horizontal( resamp, indata, outdata ); FREE( indata, 7 ); } if (Debug_i) { printf("After horiz resamp: "); print_min_max( outdata, outproj->Nr * outproj->Nc * outnl ); } return outdata; } /* * For all the grids that belong to timestep 'time' and variable 'var' * resample them to the output projection and VCS then merge them into * one final 3-D grid. */ static float *get_combined_resampled_data( struct grid_db *db, int time, int var, struct projection *outproj, struct vcs *outvcs, int outnl, int average ) { #define MAX_GRIDS 100 int numgrids; struct grid_info *g, *glist[MAX_GRIDS]; float *gdata[MAX_GRIDS]; int i, j, n; /* just a test */ if (outvcs->Nl!=outnl) { printf("***** outvcs->nl != outnl in get_c_r_d\n"); } /* Make a list of all selected grids for this timestep and variable */ g = db->Matrix[time][var]; numgrids = 0; while (g && numgridsSelectBits==ALL_BITS) { glist[numgrids] = g; numgrids++; } g = g->Sibling; } if (numgrids==0) { /* no grid data available for this timstep and variable */ return NULL; } /* Merge/stack 2-D grids into 3-D grid(s) */ if (numgrids>1) { find_and_combine_2d_grids( db, &numgrids, glist ); } /* Resample all the grids to the output proj and VCS */ n = numgrids; numgrids = 0; for (i=0;iData) { free_grid_info( glist[0] ); } return gdata[0]; } else { /* Average together the 3-D grids */ int nrncnl = outproj->Nr * outproj->Nc * outnl; float *gout = (float *) MALLOC( nrncnl * sizeof(float) ); if (average) { average_values( nrncnl, numgrids, gdata, gout ); } else { /* sort grids by order of decreasing resolution (high-res first) */ for (i=0;iProj ); res2 = proj_resolution( glist[j]->Proj ); if (res2Data) { free_grid_info( glist[i] ); } } return gout; } } /* * Make a v5d file from the table of grids and parameters found in the * v5dstruct. * * Input: db - the grid database struct describing the grid data layout * v5d - contains parameters to describe output file: * Nr = number of rows * Nc = number of columns * Projection, ProjArgs - map projection * Vertical, VertArgs - vertical coord system * filename - name of v5d output file. * maxnl - maximum number of grid levels allowed. * average - 0=use higher-res co-located data * 1=average co-located data * compressmode - bytes per datapoint in output file: 1, 2, or 4 * * Notes: Which variables and timesteps to output is determined by * examining the grid table. */ void make_output_file( struct grid_db *db, v5dstruct *v5d, char *filename, int maxnl, int average, int compressmode ) { int time, var; int xlate_time[MAXTIMES], xlate_var[MAXVARS]; int nl[IMAXVARS], lowlev[IMAXVARS]; struct projection *output_proj; struct vcs *output_vcs, *var_vcs[MAXVARS]; int numproj, numvcs; int i; #if V5D_VERSION >= 42 printf("Writing a 4.3 file!\n"); #endif /* Save current number of projections and VCSs */ numproj = db->NumProj; numvcs = db->NumVcs; /* * Finish initializing the v5d struct */ /* Output file's projection and VCS */ output_proj = new_projection( db, v5d->Projection, v5d->Nr, v5d->Nc, v5d->ProjArgs ); output_vcs = new_vcs( db, v5d->VerticalSystem, maxnl, 0, v5d->VertArgs ); /* Grid levels */ compute_grid_levels( db, output_vcs, lowlev, nl ); for (i=0;iNumVars;i++) { /* truncate number of levels to fit user specified limit */ if (lowlev[i]+nl[i]>maxnl) { if (nl[i]>maxnl) { lowlev[i] = 0; nl[i] = maxnl; } else { lowlev[i] = maxnl - nl[i]; } } } /* Setup variables */ v5d->NumVars = 0; for (var=0;varNumVars;var++) { if (db->VarSelected[var]) { if (v5d->NumVarsVarName[v5d->NumVars], db->VarNames[var], 10 ); if (db->Units[var]) { strncpy( v5d->Units[v5d->NumVars], db->Units[var], 19 ); v5d->Units[v5d->NumVars][19] = 0; } xlate_var[v5d->NumVars] = var; v5d->Nl[v5d->NumVars] = nl[var]; #if V5D_VERSION >= 42 v5d->LowLev[v5d->NumVars] = lowlev[var]; #else /* sanity check */ assert( lowlev[var] == 0 ); #endif v5d->NumVars++; } else { printf("Warning: too many variables, %d is limit,", MAXVARS ); printf(" ignoring %s\n", db->VarNames[var] ); } } } /* Setup timesteps */ v5d->NumTimes = 0; for (time=0;timeNumTimes;time++) { if (db->TimeSelected[time]) { if (v5d->NumTimesDateStamp[v5d->NumTimes] = db->DateStamp[time]; v5d->TimeStamp[v5d->NumTimes] = db->TimeStamp[time]; xlate_time[v5d->NumTimes] = time; v5d->NumTimes++; } else { printf("Warning: too many time steps, %d is limit,", MAXTIMES); printf(" ignoring %05d %06d\n", db->DateStamp[time], db->TimeStamp[time] ); } } } /* actually need a different VCS for each variable */ for (var=0;varNumVars;var++) { var_vcs[var] = new_vcs( db, v5d->VerticalSystem, v5d->Nl[var], #if V5D_VERSION >= 42 v5d->LowLev[var], #else 0, #endif v5d->VertArgs ); } v5d->CompressMode = compressmode; /* * Create the v5d file */ if (!v5dCreateFile( filename, v5d )) { printf("Error in v5dCreateFile\n"); return; } /* * Write grid data */ for (time=0;timeNumTimes;time++) { for (var=0;varNumVars;var++) { int table_time, table_var; float *data; /* Translate timestep and variable number from v5d struct indexes */ /* into grid table indexes. */ table_time = xlate_time[time]; table_var = xlate_var[var]; printf("Time: %d Var: %s\n", time+1, v5d->VarName[var] ); /* Get the resampled data for this timestep and variable */ data = get_combined_resampled_data( db, table_time, table_var, output_proj, var_vcs[var], v5d->Nl[var], average ); if (data) { v5dWriteGrid( v5d, time, var, data ); FREE( data, 9 ); } else { printf("WARNING: writing missing field for: time=%d var=%d\n", time, var ); write_missing_grid( v5d, time, var, v5d->Nr, v5d->Nc,v5d->Nl[var]); } } } v5dCloseFile( v5d ); free_resamplers(); /* free new projection and VCSs made during resampling */ for (i=db->NumProj-1; i>=numproj; i--) { free_projection( db, db->ProjList[i] ); } for (i=db->NumVcs-1; i>=numvcs; i--) { free_vcs( db, db->VcsList[i] ); } } /***************************************************************************/ /* New 5.0 stuff ***********************************************************/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ int make_output_ctx( struct grid_db *db, v5dstruct *v5d, char *filename, char *ctxname, int maxnl, int average, int compressmode, int mbs, int mf, int mc ) { int time, var; int xlate_time[MAXTIMES], xlate_var[MAXVARS]; int nl[IMAXVARS], lowlev[IMAXVARS]; struct projection *output_proj; struct vcs *output_vcs, *var_vcs[MAXVARS]; int numproj, numvcs; int i, yo; #if V5D_VERSION >=42 printf("Writing a 4.3 file!\n"); #endif /* Save current number of projections and VCSs */ numproj = db->NumProj; numvcs = db->NumVcs; /* * Finish initializing the v5d struct */ /* Output file's projection and VCS */ output_proj = new_projection( db, v5d->Projection, v5d->Nr, v5d->Nc, v5d->ProjArgs ); output_vcs = new_vcs( db, v5d->VerticalSystem, maxnl, 0, v5d->VertArgs ); /* Grid levels */ compute_grid_levels( db, output_vcs, lowlev, nl ); for (i=0;iNumVars;i++) { /* truncate number of levels to fit user specified limit */ if (lowlev[i]+nl[i]>maxnl) { if (nl[i]>maxnl) { lowlev[i] = 0; nl[i] = maxnl; } else { lowlev[i] = maxnl - nl[i]; } } } /* Setup variables */ v5d->NumVars = 0; for (var=0;varNumVars;var++) { if (db->VarSelected[var]) { if (v5d->NumVarsVarName[v5d->NumVars], db->VarNames[var], 10 ); if (db->Units[var]) { strncpy( v5d->Units[v5d->NumVars], db->Units[var], 19 ); v5d->Units[v5d->NumVars][19] = 0; } xlate_var[v5d->NumVars] = var; v5d->Nl[v5d->NumVars] = nl[var]; #if V5D_VERSION >= 42 v5d->LowLev[v5d->NumVars] = lowlev[var]; #else /* sanity check */ assert( lowlev[var] == 0 ); #endif v5d->NumVars++; } else { printf("Warning: too many variables, %d is limit,", MAXVARS ); printf(" ignoring %s\n", db->VarNames[var] ); } } } /* Setup timesteps */ v5d->NumTimes = 0; for (time=0;timeNumTimes;time++) { if (db->TimeSelected[time]) { if (v5d->NumTimesDateStamp[v5d->NumTimes] = db->DateStamp[time]; v5d->TimeStamp[v5d->NumTimes] = db->TimeStamp[time]; xlate_time[v5d->NumTimes] = time; v5d->NumTimes++; } else { printf("Warning: too many time steps, %d is limit,", MAXTIMES); printf(" ignoring %05d %06d\n", db->DateStamp[time], db->TimeStamp[time] ); } } } /* actually need a different VCS for each variable */ for (var=0;varNumVars;var++) { var_vcs[var] = new_vcs( db, v5d->VerticalSystem, v5d->Nl[var], #if V5D_VERSION >= 42 v5d->LowLev[var], #else 0, #endif v5d->VertArgs ); } v5d->CompressMode = compressmode; if (mf == 1 && mc == 0){ if (!v5dCreateFile( filename, v5d )) { printf("Error in v5dCreateFile\n"); return -1; } /* * Write grid data */ for (time=0;timeNumTimes;time++) { for (var=0;varNumVars;var++) { int table_time, table_var; float *data; /* Translate timestep and variable number from v5d struct indexes */ /* into grid table indexes. */ table_time = xlate_time[time]; table_var = xlate_var[var]; printf("Time: %d Var: %s\n", time+1, v5d->VarName[var] ); /* Get the resampled data for this timestep and variable */ data = get_combined_resampled_data( db, table_time, table_var, output_proj, var_vcs[var], v5d->Nl[var], average ); if (data) { v5dWriteGrid( v5d, time, var, data ); FREE( data, 9 ); } else { if (Debug_i) printf("missing: %d %d\n", time, var ); write_missing_grid( v5d, time, var, v5d->Nr, v5d->Nc,v5d->Nl[var]); } } } v5dCloseFile( v5d ); free_resamplers(); /* free new projection and VCSs made during resampling */ for (i=db->NumProj-1; i>=numproj; i--) { free_projection( db, db->ProjList[i] ); } for (i=db->NumVcs-1; i>=numvcs; i--) { free_vcs( db, db->VcsList[i] ); } return 1; } if (mf == 1 && mc == 1){ int yes; if (!v5dCreateFile( filename, v5d )) { printf("Error in v5dCreateFile\n"); return -1; } /* * Write grid data */ for (time=0;timeNumTimes;time++) { for (var=0;varNumVars;var++) { int table_time, table_var; float *data; /* Translate timestep and variable number from v5d struct indexes */ /* into grid table indexes. */ table_time = xlate_time[time]; table_var = xlate_var[var]; printf("Time: %d Var: %s\n", time+1, v5d->VarName[var] ); /* Get the resampled data for this timestep and variable */ data = get_combined_resampled_data( db, table_time, table_var, output_proj, var_vcs[var], v5d->Nl[var], average ); if (data) { v5dWriteGrid( v5d, time, var, data ); FREE( data, 9 ); } else { if (Debug_i) printf("missing: %d %d\n", time, var ); write_missing_grid( v5d, time, var, v5d->Nr, v5d->Nc,v5d->Nl[var]); } } } v5dCloseFile( v5d ); free_resamplers(); /* free new projection and VCSs made during resampling */ for (i=db->NumProj-1; i>=numproj; i--) { free_projection( db, db->ProjList[i] ); } for (i=db->NumVcs-1; i>=numvcs; i--) { free_vcs( db, db->VcsList[i] ); } yes = vis5d_load_v5dfile( 0, mbs, filename, ctxname); return yes; } if (mf == 0 && mc == 1){ return 0; /* TODO LATER!!!!! filename[0] = 0; yo = vis5d_load_v5dfile(0, v5d, mbs, filename, ctxname); */ if ( yo <= 0 ){ printf("not enough memory please give a file name to write to \n"); /* strcpy( message, " not enough memory, please give a file name to write to. "); show_error_widget( 0, message); */ return 0; } /* * Write grid data to a ctx */ for (time=0;timeNumTimes;time++) { for (var=0;varNumVars;var++) { int table_time, table_var; float *data; /* Translate timestep and variable number from v5d struct indexes */ /* into grid table indexes. */ table_time = xlate_time[time]; table_var = xlate_var[var]; printf("Time: %d Var: %s\n", time+1, v5d->VarName[var] ); /* Get the resampled data for this timestep and variable */ data = get_combined_resampled_data( db, table_time, table_var, output_proj, var_vcs[var], v5d->Nl[var], average ); if (data) { /*vis5d_insert_grid_into_ctx( 1, time, var, data); */ FREE( data, 9 ); } else { /***************** TO DO STUFF ***********************************/ if (Debug_i) printf("missing: %d %d\n", time, var ); write_missing_grid( v5d, time, var, v5d->Nr, v5d->Nc,v5d->Nl[var]); } } } free_resamplers(); /* free new projection and VCSs made during resampling */ for (i=db->NumProj-1; i>=numproj; i--) { free_projection( db, db->ProjList[i] ); } for (i=db->NumVcs-1; i>=numvcs; i--) { free_vcs( db, db->VcsList[i] ); } return 1; } /* strcpy(message, "you must give a file name and/or a context name please"); show_error_widget( 0, message); */ printf("it dosn't work\n"); return 0; }