続きです。
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バイトなのでしょう。


コメント