#include #include #include #include #include #include #include #define MSG_FLAG 0x80000001 #define N_BYTES 1 #define IN_TILE_DEGREES_LON 180.0 #define IN_TILE_DEGREES_LAT 180.0 #define IN_TILE_PTS_X 1250 #define IN_TILE_PTS_Y 1250 #define OUT_TILE_DEGREES_LON 180.0 #define OUT_TILE_DEGREES_LAT 180.0 #define OUT_TILE_PTS_X 1250 #define OUT_TILE_PTS_Y 1250 #define HALO_WIDTH 3 #define ZDIM 12 #define CACHESIZE 12 int **** data_cache = NULL; char ** fname_cache = NULL; int * lru = NULL; int *** supertile = NULL; int supertile_min_x = 999999; int supertile_min_y = 999999; void free_newtile(int *** x) { int i, j, k; for(i=0; i least) { least = lru[k]; least_idx = k; } } if (data_cache[least_idx] == NULL) { data_cache[least_idx] = localptr; fname_cache[least_idx] = fname; lru[least_idx] = 0; } else { free_newtile(data_cache[least_idx]); data_cache[least_idx] = localptr; free(fname_cache[least_idx]); fname_cache[least_idx] = fname; lru[least_idx] = 0; } retval = localptr; return retval; } void build_supertile(int i, int j) { int ii, jj, kk; int doflip; int *** newtile; if (i < 0) i = i + IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON); if (i >= IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON)) i = i - IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON); if (j < 0) j = j + IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT); if (j >= IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT)) j = j - IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT); if (supertile == NULL) { supertile = (int ***)malloc(sizeof(int **)*3*IN_TILE_PTS_X); for(ii=0; ii<3*IN_TILE_PTS_X; ii++) { supertile[ii] = (int **)malloc(sizeof(int *)*3*IN_TILE_PTS_Y); for(jj=0; jj<3*IN_TILE_PTS_Y; jj++) { supertile[ii][jj] = (int *)malloc(sizeof(int)*ZDIM); } } } supertile_min_x = (i / IN_TILE_PTS_X)*IN_TILE_PTS_X; supertile_min_y = (j / IN_TILE_PTS_Y)*IN_TILE_PTS_Y; /* Get tile containing (i,j) from cache*/ /* Get surrounding tiles from cache */ /* Lower-left */ ii = i - IN_TILE_PTS_X; if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; doflip = 0; jj = j - IN_TILE_PTS_Y; if (jj < 0) { doflip = 1; jj = j; ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; } newtile = get_tile_from_cache(ii, jj); if (doflip) { for(ii=0; ii= (int)(180./IN_TILE_DEGREES_LAT)*IN_TILE_PTS_Y) { doflip = 1; jj = j; ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; } newtile = get_tile_from_cache(ii, jj); if (doflip) { for(ii=0; ii= (int)(180./IN_TILE_DEGREES_LAT)*IN_TILE_PTS_Y) { doflip = 1; jj = j; ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; } newtile = get_tile_from_cache(ii, jj); if (doflip) { for(ii=0; ii= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X) ii -= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; doflip = 0; jj = j - IN_TILE_PTS_Y; if (jj < 0) { doflip = 1; jj = j; ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; } newtile = get_tile_from_cache(ii, jj); if (doflip) { for(ii=0; ii= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X) ii -= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; jj = j; newtile = get_tile_from_cache(ii, jj); for(ii=0; ii= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X) ii -= (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; doflip = 0; jj = j + IN_TILE_PTS_Y; if (jj >= (int)(180./IN_TILE_DEGREES_LAT)*IN_TILE_PTS_Y) { doflip = 1; jj = j; ii -= (int)(180./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; if (ii < 0) ii += (int)(360./IN_TILE_DEGREES_LON)*IN_TILE_PTS_X; } newtile = get_tile_from_cache(ii, jj); if (doflip) { for(ii=0; ii= IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON)) i = i - IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON); if (j < 0) j = j + IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT); if (j >= IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT)) j = j - IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT); i_src = i % IN_TILE_PTS_X + IN_TILE_PTS_X; j_src = j % IN_TILE_PTS_Y + IN_TILE_PTS_Y; /* Interpolate values from supertile */ sum = 0; n = 0; for(ii=i_src; ii<=i_src+irad; ii++) { for(jj=j_src; jj<=j_src+irad; jj++) { sum += supertile[ii][jj][k]; n++; } } if (n > 0) return sum/n; else return 0; } int is_in_supertile(int i, int j) { if (i < 0) i = i + IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON); if (i >= IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON)) i = i - IN_TILE_PTS_X*(int)(360./IN_TILE_DEGREES_LON); if (j < 0) j = j + IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT); if (j >= IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT)) j = j - IN_TILE_PTS_Y*(int)(180./IN_TILE_DEGREES_LAT); /* Check whether (i,j) is in the interior of supertile */ if ((i >= supertile_min_x) && (i < supertile_min_x+IN_TILE_PTS_X) && (j >= supertile_min_y) && (j < supertile_min_y+IN_TILE_PTS_Y)) return 1; else return 0; } int main(int argc, char ** argv) { int tile_x, tile_y, input_x, input_y, temp_x, temp_y; int i, j, k, z, ii, jj; int i_src, j_src; int *** intdata; int out_fd; int ir_rel; float r_rel; unsigned char * outdata; char out_filename[256]; r_rel = (float)IN_TILE_PTS_X/(float)OUT_TILE_PTS_X*OUT_TILE_DEGREES_LON/IN_TILE_DEGREES_LON; ir_rel = (int)rint(r_rel); /* Allocate memory to hold a single output tile */ intdata = (int ***)malloc(sizeof(int **)*(OUT_TILE_PTS_X+2*HALO_WIDTH)); for(i=0; i<(OUT_TILE_PTS_X+2*HALO_WIDTH); i++) { intdata[i] = (int **)malloc(sizeof(int *)*(OUT_TILE_PTS_Y+2*HALO_WIDTH)); for(j=0; j<(OUT_TILE_PTS_Y+2*HALO_WIDTH); j++) { intdata[i][j] = (int *)malloc(sizeof(int)*ZDIM); } } /* Allocate output buffer */ outdata = (unsigned char *)malloc((OUT_TILE_PTS_X+2*HALO_WIDTH)*(OUT_TILE_PTS_Y+2*HALO_WIDTH)*ZDIM*N_BYTES); for(tile_x=0; tile_x> (8*(N_BYTES-k-1)); } } } } write(out_fd,(void *)outdata,(OUT_TILE_PTS_X+2*HALO_WIDTH)*(OUT_TILE_PTS_Y+2*HALO_WIDTH)*ZDIM*N_BYTES); close(out_fd); printf("Wrote file %s\n",out_filename); } } /* Deallocate memory */ for(i=0; i<(OUT_TILE_PTS_X+2*HALO_WIDTH); i++) { for(j=0; j<(OUT_TILE_PTS_Y+2*HALO_WIDTH); j++) { free(intdata[i][j]); } free(intdata[i]); } free(intdata); return 0; }