続きです。
C言語で、バイナリデータを読み込むプログラムを作りたいと思います。
最初に、引数で指定したmdpファイルを読み込む簡単なプログラムから。
takk@deb8:~/Desktop$ cat -n read-mdp.c 1 #include <stdio.h> 2 3 int main(int argc, char* argv[]) 4 { 5 int c; 6 int n = 0; 7 FILE *fp = fopen(argv[1], "r"); 8 9 while((c = fgetc(fp)) != EOF){ 10 n ++; 11 } 12 printf("length:%d\n",n); 13 14 return 0; 15 }
takk@deb8:~/Desktop$ gcc t.c takk@deb8:~/Desktop$ ./a.out file-1.mdp length:2061 takk@deb8:~/Desktop$ wc -c file-1.mdp 2061 file-1.mdp takk@deb8:~/Desktop$
簡単なファイル読み込みのプログラムが確認できたら、PAC文字列を探す処理を入れてみます。
連続4回照合成功したら、情報を表示してプログラムを終了する処理です。
takk@deb8:~/Desktop$ cat -n read-mdp.c 1 #include <stdio.h> 2 3 int main(int argc, char* argv[]) 4 { 5 char ptn[] = "PAC "; 6 int c,len; 7 int n = 0; 8 int ind = 0; 9 FILE *fp = fopen(argv[1], "r"); 10 11 while((c = fgetc(fp)) != EOF){ 12 if((char)c == ptn[ind]) 13 ind++; 14 else 15 ind=0; 16 n ++; 17 if(ind == 4){ 18 ind = 0; 19 len = fgetc(fp); 20 len |= fgetc(fp) << 8; 21 printf("index:%x length:%d\n", n - 4, len); 22 break; 23 } 24 } 25 return 0; 26 }
takk@deb8:~/Desktop$ gcc read-mdp.c takk@deb8:~/Desktop$ ./a.out file-1.mdp index:528 length:333 takk@deb8:~/Desktop$
最後にfseekでファイルポインタの位置を次のブロックまで移動させて、すべてのPAC文字列の位置と各データの長さを表示するプログラムにします。データ長2バイトでは足りないかもしれませんが。
takk@deb8:~/Desktop$ cat read-mdp.c 1 #include <stdio.h> 2 3 int main(int argc, char* argv[]) 4 { 5 char ptn[] = "PAC "; 6 int c,len; 7 int n = 0; 8 int ind = 0; 9 FILE *fp = fopen(argv[1], "r"); 10 11 while((c = fgetc(fp)) != EOF){ 12 if((char)c == ptn[ind]) 13 ind++; 14 else 15 ind=0; 16 n++; 17 if(ind == 4){ 18 ind = 0; 19 len = fgetc(fp); 20 len |= fgetc(fp) << 8; 21 printf("index:%x length:%d\n", n - 4, len); 22 fseek(fp, len - 6, SEEK_CUR); 23 n += len - 4; 24 } 25 } 26 27 return 0; 28 }
実行すると、おそらく画像データであろうPACブロックの位置とデータ長が取得できます。
takk@deb8:~/Desktop$ gcc read-mdp.c takk@deb8:~/Desktop$ ./a.out file-1.mdp index:528 length:333 index:675 length:136 index:6fd length:136 index:785 length:136 takk@deb8:~/Desktop$ ./a.out file-2.mdp index:528 length:333 index:675 length:136 index:6fd length:248 index:7f5 length:136 takk@deb8:~/Desktop$
takk@deb8:~/Desktop$ strings -tx file-1.mdp | grep PAC 528 PAC M 675 PAC 6fd PAC 785 PAC takk@deb8:~/Desktop$ strings -tx file-2.mdp | grep PAC 528 PAC M 675 PAC 6fd PAC 7f4 iPAC takk@deb8:~/Desktop$
最後が7f4となっていますが、文字列PACの一つ前の文字からのオフセットとなっているためです。
では、もう少し大きなデータで試してみます。
takk@deb8:~/Desktop$ ls -l summerwars.mdp -rw-r--r-- 1 takk takk 4709500 2月 28 05:55 summerwars.mdp takk@deb8:~/Desktop$
takk@deb8:~/Desktop$ ./a.out summerwars.mdp index:3fe length:13430 index:23874 length:4372 index:414988 length:37620
サイズが合いません。データ長が2BYTEではやはり足りなかったです。
takk@deb8:~/Desktop$ od -tx1 -j 0x23874 -N 10 summerwars.mdp 0434164 50 41 43 20 14 11 3f 00 00 00 0434176 takk@deb8:~/Desktop$ ruby -e 'printf "%x", 0x3f1114 + 0x23874' 414988
埋め込まれたデータ長が4バイトと仮定して計算すると、数字が合うので、おそらく各PACブロックのデータ長は4バイトなのでしょう。
コメント