#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
void printbc(unsigned char v) {
unsigned char mask = (char)1 << (sizeof(v) * CHAR_BIT - 1);
do putchar(mask & v ? '1' : '0');
while (mask >>= 1);
}
void printb(unsigned int v) {
unsigned int mask = (int)1 << (sizeof(v) * CHAR_BIT - 1);
do putchar(mask & v ? '1' : '0');
while (mask >>= 1);
}
void putb(unsigned int v) {
putchar('0'), putchar('b'), printb(v), putchar('\n');
}
char *read_str( FILE *fp,
int len ){
char *str = malloc(sizeof(char)*len);
if( fread( str, sizeof(char), len, fp ) < len ){
printf("Error while reading.\n");
exit( EXIT_FAILURE );
}
return str;
}
int read_char( FILE *fp ){
char c;
if( fread( &c, sizeof(c), 1, fp ) < 1 ){
printf("Error while reading.\n");
exit( EXIT_FAILURE );
}
return c;
}
int read_uchar( FILE *fp ){
unsigned char c;
if( fread( &c, sizeof(c), 1, fp ) < 1 ){
printf("Error while reading.\n");
exit( EXIT_FAILURE );
}
return c;
}
short read_short( FILE *fp ){
short n;
if( fread( &n, sizeof(n), 1, fp ) < 1 ){
printf("Error while reading.\n");
exit( EXIT_FAILURE );
}
return n;
}
int read_int( FILE *fp ){
int n;
if( fread( &n, sizeof(n), 1, fp ) < 1 ){
printf("Error while reading.\n");
exit( EXIT_FAILURE );
}
return n;
}
int read_double( FILE *fp ){
double f;
if( fread( &f, sizeof(f), 1, fp ) < 1 ){
printf("Error while reading.\n");
exit( EXIT_FAILURE );
}
return f;
}
short *levels;
struct{
unsigned char level;
unsigned char rep;
} tableLevRep[128];
int unpack( unsigned char *data,
int size,
short *out ){
int ii, ip = 0, op = 0;
unsigned char d;
while( ip < size ) {
d = data[ip++];
if( ( d & 0x80 ) == 0 ) {
for( ii = tableLevRep[d].rep + 2 ; ii > 0 ; ii-- )
out[op++] = levels[ tableLevRep[d].level ];
} else if( ( d & 0xE0 ) == 0xC0 ) {
for( ii = data[ip++] + 2 ; ii > 0; ii-- )
out[op++] = levels[ d & 0x1F ];
} else if( ( d & 0xC0 ) == 0x80 ) {
out[op++] = levels[ d & 0x3F ];
} else if( d == 0xFE ) {
out[op++] = levels[ data[ip++] ];
} else {
fprintf( stderr, "解凍できませんでした\n" );
exit(1);
}
}
return op;
}
int main( int argc, char *argv[] ){
if( argc != 3 ){
fprintf( stderr, "Invalid number of argument.\n" );
fprintf( stderr, "[Usage] PROGRAM file_inp file_out\n" );
exit( EXIT_FAILURE );
}
char *file_inp = argv[1];
char *file_out = argv[2];
FILE *fp = fopen( file_inp, "rb" );
if( fp == NULL ){
fprintf( stderr, "Can't open a file: %s\n", file_inp );
exit( EXIT_FAILURE );
}
FILE *wfp = fopen( file_out, "wb" );
if( wfp == NULL ){
printf( "Can't open a file: %s\n", file_out );
exit( EXIT_FAILURE );
}
char *identifier = read_str( fp, 6 );
char *version = read_str( fp, 5 );
char *editor_comment = read_str( fp, 66 );
unsigned char num1 = read_uchar( fp );
unsigned char num2 = read_uchar( fp );
unsigned char num3 = read_uchar( fp );
printf( "識別子 : %s\n", identifier );
printf( "版番号 : %s\n", version );
printf( "作成者コメント: %s\n", editor_comment );
printf( "<CR> %d\n", num1 );
printf( "<LF> %d\n", num2 );
printf( "<NULL> %d\n", num3 );
int nmax_data;
fread( &nmax_data, sizeof(nmax_data), 1, fp );
printf( "データ数: %d\n", nmax_data );
short YYYY;
unsigned char MM;
unsigned char DD;
unsigned char hh;
unsigned char mm;
short kind;
char *spare_index;
int position;
int i;
int imax = nmax_data;
for( i=0; i<imax; i++ ){
YYYY = read_short( fp );
MM = read_uchar( fp );
DD = read_uchar( fp );
hh = read_uchar( fp );
mm = read_uchar( fp );
kind = read_short( fp );
spare_index = read_str( fp, 8 );
position = read_int( fp );
printf( "%2d %04d/%02d/%02d_%02d:%02d\n", i,YYYY,MM,DD,hh,mm );
}
char *spare_grid1 = read_str( fp, 2);
short map_type = read_short( fp );
int lon = read_int( fp );
int lat = read_int( fp );
int intvl_h = read_int( fp );
int intvl_v = read_int( fp );
short hmax = read_short( fp );
short vmax = read_short( fp );
char *spare_grid2 = read_str( fp, 16 );
printf( "地図種別: %d\n", map_type );
printf( "経度: %d, 緯度: %d\n", lon, lat );
printf( "横格子間隔: %d, 縦格子間隔: %d\n", intvl_h, intvl_v );
printf( "横格子数: %d, 縦格子数: %d\n", hmax, vmax );
short compress_mode = read_short( fp );
short level_max = read_short( fp );
printf( "圧縮方法: %d\n", compress_mode );
printf( "レベル数: %d\n", level_max );
levels = malloc(sizeof(short)*level_max);
printf( " レベル値 雨量(0.1 mm)\n");
imax = level_max;
for( i=0; i<imax; i++ ){
short val = read_short( fp );
levels[i] = val;
printf( " %d %d\n", i,val );
}
short size_table = read_short( fp );
printf( "表の大きさ: %d\n", size_table );
imax = size_table;
printf( " No. レベル値 反復数-2 \n");
for( i=0; i<imax; i++ ){
unsigned char level = read_uchar( fp );
unsigned char repeat = read_uchar( fp );
tableLevRep[i].level = level;
tableLevRep[i].rep = repeat;
printf( "%3d %4d %6d\n", i, level, repeat );
}
printf( "Decoding.\n" );
int n_data;
for( n_data=0; n_data<nmax_data; n_data++ ){
printf( "Data %2d\n", n_data );
int size = read_int( fp );
printf( " 圧縮後の大きさ: %d\n", size );
unsigned char data[size];
imax = size;
for( i=0; i<imax; i++ ){
data[i] = read_uchar( fp );
}
short out[hmax*vmax];
if( unpack( data, size, out) != hmax*vmax ){
printf ( "Extended data size is not equal to hmax*vmax." );
exit( EXIT_FAILURE );
}
if( fwrite( out, sizeof(out[0]), hmax*vmax, wfp ) < hmax*vmax ){
printf( "Writing failed.\n" );
exit( EXIT_FAILURE );
}
char *state = read_str( fp, 8 );
int n_amedas = read_int( fp );
printf( " 解析に使用したアメダスの総数: %d\n", n_amedas );
}
if( fclose( wfp ) == EOF ){
fprintf( stderr, "File closing failed.\n" );
exit( EXIT_FAILURE );
}
return 0;
}