9 #define MSG_FLAG 0x80000001
12 #define IN_TILE_DEGREES_LON 10.0
13 #define IN_TILE_DEGREES_LAT 10.0
14 #define IN_TILE_PTS_X 1200
15 #define IN_TILE_PTS_Y 1200
16 #define OUT_TILE_DEGREES_LON 20.0
17 #define OUT_TILE_DEGREES_LAT 20.0
18 #define OUT_TILE_PTS_X 600
19 #define OUT_TILE_PTS_Y 600
27 int **** data_cache
= NULL
;
28 char ** fname_cache
= NULL
;
31 int *** supertile
= NULL
;
32 int supertile_min_x
= 999999;
33 int supertile_min_y
= 999999;
35 void free_newtile(int *** x
)
39 for(i
=0; i
<IN_TILE_PTS_X
; i
++)
41 for(j
=0; j
<IN_TILE_PTS_Y
; j
++)
50 int *** read_tile(char * fname
)
54 unsigned char buf
[IN_TILE_PTS_X
*IN_TILE_PTS_Y
*ZDIM
*N_BYTES
];
57 retval
= (int ***)malloc(sizeof(int **)*IN_TILE_PTS_X
);
58 for(i
=0; i
<IN_TILE_PTS_X
; i
++)
60 retval
[i
] = (int **)malloc(sizeof(int *)*IN_TILE_PTS_Y
);
61 for(j
=0; j
<IN_TILE_PTS_Y
; j
++)
63 retval
[i
][j
] = (int *)malloc(sizeof(int)*ZDIM
);
67 if ((fd
= open(fname
,O_RDONLY
)) == -1)
69 fprintf(stderr
,"Error opening source file %s\n", fname
);
73 read(fd
, (void *)&buf
, IN_TILE_PTS_X
*IN_TILE_PTS_Y
*ZDIM
*N_BYTES
);
77 /* Put buf into retval */
78 for(i
=0; i
<IN_TILE_PTS_X
; i
++)
80 for(j
=0; j
<IN_TILE_PTS_Y
; j
++)
85 for(b
=0; b
<N_BYTES
; b
++)
87 retval
[i
][j
][k
] |= buf
[k
*N_BYTES
*IN_TILE_PTS_X
*IN_TILE_PTS_Y
+j
*N_BYTES
*IN_TILE_PTS_X
+i
*N_BYTES
+b
] << 8*(N_BYTES
-b
-1);
96 int *** get_tile_from_cache(int i
, int j
)
98 int ii
, jj
, kk
, k
, least
, least_idx
;
99 int *** retval
, *** localptr
;
102 fname
= (char *)malloc(256);
104 i
= (i
/IN_TILE_PTS_X
)*IN_TILE_PTS_X
+1;
105 j
= (j
/IN_TILE_PTS_Y
)*IN_TILE_PTS_Y
+1;
107 snprintf(fname
,256,"%5.5i-%5.5i.%5.5i-%5.5i",i
,i
+IN_TILE_PTS_X
-1,j
,j
+IN_TILE_PTS_Y
-1);
109 /* Find out whether tile containing (i,j) is in cache */
110 if (data_cache
!= NULL
)
112 for(k
=0; k
<CACHESIZE
; k
++)
114 if (fname_cache
[k
] != NULL
)
116 if (strncmp(fname_cache
[k
],fname
,256) == 0)
119 retval
= data_cache
[k
];
126 /* If not, read from file */
127 localptr
= read_tile(fname
);
129 /* Also store tile in the cache */
130 if (data_cache
== NULL
)
132 data_cache
= (int ****)malloc(sizeof(int ***)*CACHESIZE
);
133 fname_cache
= (char **)malloc(sizeof(char *)*CACHESIZE
);
134 lru
= (int *)malloc(sizeof(int)*CACHESIZE
);
135 for(k
=0; k
<CACHESIZE
; k
++)
137 data_cache
[k
] = NULL
;
138 fname_cache
[k
] = NULL
;
145 for(k
=0; k
<CACHESIZE
; k
++)
155 if (data_cache
[least_idx
] == NULL
)
157 data_cache
[least_idx
] = localptr
;
158 fname_cache
[least_idx
] = fname
;
163 free_newtile(data_cache
[least_idx
]);
164 data_cache
[least_idx
] = localptr
;
165 free(fname_cache
[least_idx
]);
166 fname_cache
[least_idx
] = fname
;
174 void build_supertile(int i
, int j
)
181 i
= i
+ IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
);
182 if (i
>= IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
))
183 i
= i
- IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
);
185 j
= j
+ IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
);
186 if (j
>= IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
))
187 j
= j
- IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
);
189 if (supertile
== NULL
)
191 supertile
= (int ***)malloc(sizeof(int **)*3*IN_TILE_PTS_X
);
192 for(ii
=0; ii
<3*IN_TILE_PTS_X
; ii
++)
194 supertile
[ii
] = (int **)malloc(sizeof(int *)*3*IN_TILE_PTS_Y
);
195 for(jj
=0; jj
<3*IN_TILE_PTS_Y
; jj
++)
197 supertile
[ii
][jj
] = (int *)malloc(sizeof(int)*ZDIM
);
202 supertile_min_x
= (i
/ IN_TILE_PTS_X
)*IN_TILE_PTS_X
;
203 supertile_min_y
= (j
/ IN_TILE_PTS_Y
)*IN_TILE_PTS_Y
;
205 /* Get tile containing (i,j) from cache*/
206 /* Get surrounding tiles from cache */
209 ii
= i
- IN_TILE_PTS_X
;
210 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
212 jj
= j
- IN_TILE_PTS_Y
;
217 ii
-= (int)(180./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
218 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
220 newtile
= get_tile_from_cache(ii
, jj
);
223 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
225 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
227 for(kk
=0; kk
<ZDIM
; kk
++)
228 supertile
[ii
][jj
][kk
] = newtile
[ii
][IN_TILE_PTS_Y
-1-jj
][kk
];
234 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
236 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
238 for(kk
=0; kk
<ZDIM
; kk
++)
239 supertile
[ii
][jj
][kk
] = newtile
[ii
][jj
][kk
];
245 ii
= i
- IN_TILE_PTS_X
;
246 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
248 newtile
= get_tile_from_cache(ii
, jj
);
249 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
251 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
253 for(kk
=0; kk
<ZDIM
; kk
++)
254 supertile
[ii
][jj
+IN_TILE_PTS_Y
][kk
] = newtile
[ii
][jj
][kk
];
259 ii
= i
- IN_TILE_PTS_X
;
260 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
262 jj
= j
+ IN_TILE_PTS_Y
;
263 if (jj
>= (int)(180./IN_TILE_DEGREES_LAT
)*IN_TILE_PTS_Y
)
267 ii
-= (int)(180./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
268 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
270 newtile
= get_tile_from_cache(ii
, jj
);
273 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
275 for(jj
=0; jj
<IN_TILE_PTS_X
; jj
++)
277 for(kk
=0; kk
<ZDIM
; kk
++)
278 supertile
[ii
][jj
+2*IN_TILE_PTS_Y
][kk
] = newtile
[ii
][IN_TILE_PTS_Y
-1-jj
][kk
];
284 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
286 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
288 for(kk
=0; kk
<ZDIM
; kk
++)
289 supertile
[ii
][jj
+2*IN_TILE_PTS_Y
][kk
] = newtile
[ii
][jj
][kk
];
297 jj
= j
- IN_TILE_PTS_Y
;
302 ii
-= (int)(180./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
303 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
305 newtile
= get_tile_from_cache(ii
, jj
);
308 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
310 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
312 for(kk
=0; kk
<ZDIM
; kk
++)
313 supertile
[ii
+IN_TILE_PTS_X
][jj
][kk
] = newtile
[ii
][IN_TILE_PTS_Y
-1-jj
][kk
];
319 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
321 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
323 for(kk
=0; kk
<ZDIM
; kk
++)
324 supertile
[ii
+IN_TILE_PTS_X
][jj
][kk
] = newtile
[ii
][jj
][kk
];
330 newtile
= get_tile_from_cache(i
, j
);
331 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
333 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
335 for(kk
=0; kk
<ZDIM
; kk
++)
336 supertile
[ii
+IN_TILE_PTS_X
][jj
+IN_TILE_PTS_Y
][kk
] = newtile
[ii
][jj
][kk
];
343 jj
= j
+ IN_TILE_PTS_Y
;
344 if (jj
>= (int)(180./IN_TILE_DEGREES_LAT
)*IN_TILE_PTS_Y
)
348 ii
-= (int)(180./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
349 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
351 newtile
= get_tile_from_cache(ii
, jj
);
354 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
356 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
358 for(kk
=0; kk
<ZDIM
; kk
++)
359 supertile
[ii
+IN_TILE_PTS_X
][jj
+2*IN_TILE_PTS_Y
][kk
] = newtile
[ii
][IN_TILE_PTS_Y
-1-jj
][kk
];
365 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
367 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
369 for(kk
=0; kk
<ZDIM
; kk
++)
370 supertile
[ii
+IN_TILE_PTS_X
][jj
+2*IN_TILE_PTS_Y
][kk
] = newtile
[ii
][jj
][kk
];
376 ii
= i
+ IN_TILE_PTS_X
;
377 if (ii
>= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
) ii
-= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
379 jj
= j
- IN_TILE_PTS_Y
;
384 ii
-= (int)(180./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
385 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
387 newtile
= get_tile_from_cache(ii
, jj
);
390 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
392 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
394 for(kk
=0; kk
<ZDIM
; kk
++)
395 supertile
[ii
+2*IN_TILE_PTS_X
][jj
][kk
] = newtile
[ii
][IN_TILE_PTS_Y
-1-jj
][kk
];
401 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
403 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
405 for(kk
=0; kk
<ZDIM
; kk
++)
406 supertile
[ii
+2*IN_TILE_PTS_X
][jj
][kk
] = newtile
[ii
][jj
][kk
];
412 ii
= i
+ IN_TILE_PTS_X
;
413 if (ii
>= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
) ii
-= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
415 newtile
= get_tile_from_cache(ii
, jj
);
416 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
418 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
420 for(kk
=0; kk
<ZDIM
; kk
++)
421 supertile
[ii
+2*IN_TILE_PTS_X
][jj
+IN_TILE_PTS_Y
][kk
] = newtile
[ii
][jj
][kk
];
426 ii
= i
+ IN_TILE_PTS_X
;
427 if (ii
>= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
) ii
-= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
429 jj
= j
+ IN_TILE_PTS_Y
;
430 if (jj
>= (int)(180./IN_TILE_DEGREES_LAT
)*IN_TILE_PTS_Y
)
434 ii
-= (int)(180./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
435 if (ii
< 0) ii
+= (int)(360./IN_TILE_DEGREES_LON
)*IN_TILE_PTS_X
;
437 newtile
= get_tile_from_cache(ii
, jj
);
440 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
442 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
444 for(kk
=0; kk
<ZDIM
; kk
++)
445 supertile
[ii
+2*IN_TILE_PTS_X
][jj
+2*IN_TILE_PTS_Y
][kk
] = newtile
[ii
][IN_TILE_PTS_Y
-1-jj
][kk
];
451 for(ii
=0; ii
<IN_TILE_PTS_X
; ii
++)
453 for(jj
=0; jj
<IN_TILE_PTS_Y
; jj
++)
455 for(kk
=0; kk
<ZDIM
; kk
++)
456 supertile
[ii
+2*IN_TILE_PTS_X
][jj
+2*IN_TILE_PTS_Y
][kk
] = newtile
[ii
][jj
][kk
];
462 void get_value(int * num_cats
, int i
, int j
, int k
, int irad
)
470 i
= i
+ IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
);
471 if (i
>= IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
))
472 i
= i
- IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
);
474 j
= j
+ IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
);
475 if (j
>= IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
))
476 j
= j
- IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
);
478 i_src
= i
% IN_TILE_PTS_X
+ IN_TILE_PTS_X
;
479 j_src
= j
% IN_TILE_PTS_Y
+ IN_TILE_PTS_Y
;
481 /* Interpolate values from supertile */
482 for(ii
=0; ii
<NCATS
; ii
++)
485 for(ii
=i_src
-irad
; ii
<=i_src
+irad
; ii
++)
487 for(jj
=j_src
-irad
; jj
<=j_src
+irad
; jj
++)
489 num_cats
[supertile
[ii
][jj
][k
]-CATMIN
]++;
495 for(ii=i_src-irad; ii<=i_src+irad; ii++)
497 for(jj=j_src-irad; jj<=j_src+irad; jj++)
499 sum += supertile[i_src][j_src][k];
504 if (n > 0) return sum/n;
509 int is_in_supertile(int i
, int j
)
512 i
= i
+ IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
);
513 if (i
>= IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
))
514 i
= i
- IN_TILE_PTS_X
*(int)(360./IN_TILE_DEGREES_LON
);
516 j
= j
+ IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
);
517 if (j
>= IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
))
518 j
= j
- IN_TILE_PTS_Y
*(int)(180./IN_TILE_DEGREES_LAT
);
520 /* Check whether (i,j) is in the interior of supertile */
521 if ((i
>= supertile_min_x
) && (i
< supertile_min_x
+IN_TILE_PTS_X
) &&
522 (j
>= supertile_min_y
) && (j
< supertile_min_y
+IN_TILE_PTS_Y
))
528 int main(int argc
, char ** argv
)
530 int tile_x
, tile_y
, input_x
, input_y
, temp_x
, temp_y
, temp
;
531 int i
, j
, k
, z
, ii
, jj
;
538 unsigned char * outdata
;
539 char out_filename
[256];
541 r_rel
= (float)IN_TILE_PTS_X
/(float)OUT_TILE_PTS_X
*OUT_TILE_DEGREES_LON
/IN_TILE_DEGREES_LON
;
542 ir_rel
= (int)rint(r_rel
);
544 /* Allocate memory to hold a single output tile */
545 intdata
= (int ***)malloc(sizeof(int **)*(OUT_TILE_PTS_X
+2*HALO_WIDTH
));
546 for(i
=0; i
<(OUT_TILE_PTS_X
+2*HALO_WIDTH
); i
++)
548 intdata
[i
] = (int **)malloc(sizeof(int *)*(OUT_TILE_PTS_Y
+2*HALO_WIDTH
));
549 for(j
=0; j
<(OUT_TILE_PTS_Y
+2*HALO_WIDTH
); j
++)
551 intdata
[i
][j
] = (int *)malloc(sizeof(int)*ZDIM
);
555 num_cats
= (int *)malloc(sizeof(int)*NCATS
);
557 /* Allocate output buffer */
558 outdata
= (unsigned char *)malloc((OUT_TILE_PTS_X
+2*HALO_WIDTH
)*(OUT_TILE_PTS_Y
+2*HALO_WIDTH
)*ZDIM
*N_BYTES
);
560 for(tile_x
=0; tile_x
<OUT_TILE_PTS_X
*(int)(360.0/OUT_TILE_DEGREES_LON
); tile_x
+=OUT_TILE_PTS_X
)
562 for(tile_y
=0; tile_y
<OUT_TILE_PTS_Y
*(int)(180.0/OUT_TILE_DEGREES_LAT
); tile_y
+=OUT_TILE_PTS_Y
)
564 /* Build name of output file for current tile_x and tile_y */
565 sprintf(out_filename
,"retiled/%5.5i-%5.5i.%5.5i-%5.5i",tile_x
+1,tile_x
+OUT_TILE_PTS_X
,tile_y
+1,tile_y
+OUT_TILE_PTS_Y
);
567 /* Initialize the output data for current tile */
568 for(i
=0; i
<(OUT_TILE_PTS_X
+2*HALO_WIDTH
); i
++)
570 for(j
=0; j
<(OUT_TILE_PTS_Y
+2*HALO_WIDTH
); j
++)
572 intdata
[i
][j
][0] = MSG_FLAG
;
576 /* Attempt to open output file */
577 if ((out_fd
= open(out_filename
, O_WRONLY
|O_CREAT
|O_TRUNC
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
)) == -1)
579 fprintf(stderr
, "Error: Could not create or open file %s\n", out_filename
);
583 /* Fill tile with data */
584 for(i
=-1*HALO_WIDTH
; i
<OUT_TILE_PTS_X
+HALO_WIDTH
; i
++)
586 for(j
=-1*HALO_WIDTH
; j
<OUT_TILE_PTS_Y
+HALO_WIDTH
; j
++)
588 if (intdata
[i
+HALO_WIDTH
][j
+HALO_WIDTH
][0] == MSG_FLAG
)
590 i_src
= ir_rel
*(tile_x
+i
);
591 j_src
= ir_rel
*(tile_y
+j
);
593 build_supertile(i_src
,j_src
);
595 for(ii
=-1*HALO_WIDTH
; ii
<OUT_TILE_PTS_X
+HALO_WIDTH
; ii
++)
597 for(jj
=-1*HALO_WIDTH
; jj
<OUT_TILE_PTS_Y
+HALO_WIDTH
; jj
++)
599 i_src
= ir_rel
*(tile_x
+ii
);
600 j_src
= ir_rel
*(tile_y
+jj
);
601 if (is_in_supertile(i_src
,j_src
))
603 get_value(num_cats
, i_src
, j_src
, 0, ir_rel
-1);
604 intdata
[ii
+HALO_WIDTH
][jj
+HALO_WIDTH
][0] = CATMIN
-1;
606 for(k
=0; k
<NCATS
; k
++)
608 if (num_cats
[k
] >= temp
)
611 intdata
[ii
+HALO_WIDTH
][jj
+HALO_WIDTH
][0] = k
+CATMIN
;
622 /* Write out the data */
623 for(i
=0; i
<(OUT_TILE_PTS_X
+2*HALO_WIDTH
); i
++)
625 for(j
=0; j
<(OUT_TILE_PTS_Y
+2*HALO_WIDTH
); j
++)
627 for(z
=0; z
<ZDIM
; z
++)
629 for(k
=0; k
<N_BYTES
; k
++)
631 outdata
[z
*N_BYTES
*(OUT_TILE_PTS_Y
+2*HALO_WIDTH
)*(OUT_TILE_PTS_X
+2*HALO_WIDTH
)+j
*N_BYTES
*(OUT_TILE_PTS_X
+2*HALO_WIDTH
)+i
*N_BYTES
+k
] =
632 (intdata
[i
][j
][z
] & (0xff << 8*(N_BYTES
-k
-1))) >> (8*(N_BYTES
-k
-1));
637 write(out_fd
,(void *)outdata
,(OUT_TILE_PTS_X
+2*HALO_WIDTH
)*(OUT_TILE_PTS_Y
+2*HALO_WIDTH
)*ZDIM
*N_BYTES
);
639 printf("Wrote file %s\n",out_filename
);
645 /* Deallocate memory */
646 for(i
=0; i
<(OUT_TILE_PTS_X
+2*HALO_WIDTH
); i
++)
648 for(j
=0; j
<(OUT_TILE_PTS_Y
+2*HALO_WIDTH
); j
++)