model "JPEGファイルを読み込んで、マーカを解析する" { // ファイルパス macro dir,file,ext; pathsplit $(pathname), dir,file,ext; // 手続き procedure strings siz,len { // 現在のファイルポインタ位置から、+sizバイトまでの間で、 // 長さlen文字以上の印刷可能文字(0x20〜0x7e)を探して、表示する。 // 表示したバイト数を変数stringsに返す。 nvar len=4; var slen; macro str; var fpos; var fpos_end; var cmp; var cchr; macro schr; ftell fin,fpos; fpos_end=fpos + siz; while (fpos=len) { gsub "#","#",str; fprint fout," "$(str); strings=strings + slen; } slen=0; mlet str=""; } else { chrcat str,cchr; } ftell fin,fpos; } strlen slen=$(str); if (slen>=len) { gsub "#","#",str; fprint fout," "$(str); strings=strings + slen; } } procedure analyze_marker { // 0xffを読み込んだ直後のファイルポインタで実行する。 // マーカを読み込む var mkr; fgetb fin,mkr; if (mkr=0 | mkr=0xff) { // マーカではない。 return; } mlet NUM_FORM="%08x"; fprint fout,"(#) ",fpos - 1; mlet NUM_FORM="%02x"; fprint fout,"マーカff# ",mkr; var fpos; ftell fin,fpos; // マーカ毎に解析する if (mkr=0xd8) { fprint fout,"SOI"$,; return; } elif (mkr=0xd9) { fprint fout,"EOI"$,; return; } elif (0xd0<=mkr & mkr<=0xd7) { mlet NUM_FORM="%g"; fprint fout,"RST#"$,,mkr - 0xd0; return; } elif (mkr=0xc4) { fprint fout,"DHT"; } elif (mkr=0xda) { fprint fout,"SOS"; } elif (mkr=0xdb) { fprint fout,"DQT"; } elif (mkr=0xdc) { fprint fout,"DNL"; } elif (mkr=0xdd) { fprint fout,"DRI"; } elif (mkr=0xfe) { fprint fout,"COM"; } elif (0xe0<=mkr & mkr<=0xef) { mlet NUM_FORM="%g"; fprint fout,"APP#",mkr - 0xe0; } elif (0xc0<=mkr & mkr<=0xcf) { mlet NUM_FORM="%g"; fprint fout,"SOF#",mkr - 0xc0; } else { fprint fout,"unknown"$,; return; } // マーカサイズ var siz; fgetb fin,siz; fgetb fin,bdt; siz=@(siz<<8 | bdt&0xff); mlet NUM_FORM="%02x"; fprint fout," サイズ0x#",siz; // データを解析する if (0xe0<=mkr & mkr<=0xef | mkr=0xfe) { // APPn, COM fprint fout,$," "; strings siz; } elif (mkr=0xdb) { // DQT var ntab=(siz - 2)/65; marray acc:0="8ビット","16ビット"; var idx=0; while (idx>4)))" 番号#",@(bdt&0x0f); // テーブル表示 var idx2; var tab; var pqn; pqn=@(bdt>>4); if (pqn=0) { // 精度8ビット mlet NUM_FORM="%02x"; } else { // 精度16ビット mlet NUM_FORM="%04x"; } fprint fout,$," "; idx2=0; while (idx2<64) { fgetb fin,tab; if (pqn=1) { // 16ビット fgetb fin,bdt; tab=@(tab<<8 + bdt&0xff); } fprint fout,"# ",tab; idx2=idx2 + 1; } idx=idx + 1; fseek fin,fpos + 2 + idx*65; } } elif (mkr=0xc4) { // DHT var fpos2; marray cls:0="DC","AC"; repeat { fgetb fin,bdt; mlet NUM_FORM="%g"; fprint fout,$," クラス"$(cls#(@(bdt>>4)))" 番号#", @(bdt&0x0f); var dsiz; var idx; mlet NUM_FORM="%02x"; fprint fout,$," Ln: "; varray hl:0=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16; idx=0; while (idx<16) { fgetb fin,bdt; hl#(idx)=bdt; dsiz=dsiz + bdt; fprint fout,"# ",bdt; idx=idx + 1; } idx=0; while (idx<16) { dsiz=hl#(idx); if (dsiz>0) { mlet NUM_FORM="%g"; fprint fout,$," V#: ",idx + 1; } while (dsiz>0) { fgetb fin,bdt; mlet NUM_FORM="%02x"; fprint fout,"# ",bdt; dsiz= dsiz - 1; } idx=idx + 1; } ftell fin,fpos2; } until (fpos2>=fpos + siz); } elif (mkr=0xc0) { // SOF var pp; var yy; var xx; var nf; fgetb fin,pp; fgetb fin,yy; fgetb fin,bdt; yy=@(yy<<8 + bdt&0xff); fgetb fin,xx; fgetb fin,bdt; xx=@(xx<<8 + bdt&0xff); fgetb fin,nf; mlet NUM_FORM="%g"; fprint fout,$," P=# X=# Y=# Nf=#",pp,xx,yy,nf; var cc; var hv; var tq; var idx; idx=0; while (idx>4),@(hv&0xf),tq; idx=idx + 1; } } elif (mkr=0xda) { // SOS var ns; var cs; var da; var ss; var se; var hl; mlet NUM_FORM="%g"; fgetb fin,ns; var idx; idx=0; while (idx>4),@(da&0xf); idx=idx + 1; } fgetb fin,ss; fgetb fin,se; fgetb fin,hl; fprint fout,$," Ss=# Se=# Ah=# Al=#",ss,se,@(hl>>4),@(hl&0xf); } elif (mkr=0xdc) { // DNL var nl; fgetb fin,nl; fgetb fin,bdt; nl=@(nl<<8 + bdt&0xff); mlet NUM_FORM="%g"; fprint fout,$," NL=#",nl; } elif (mkr=0xdd) { // DRI var ri; fgetb fin,ri; fgetb fin,bdt; ri=@(ri<<8 + bdt&0xff); mlet NUM_FORM="%g"; fprint fout,$," Ri=#",ri; } fprint fout,$,; // マーカ位置からsiz分送る fseek fin,fpos + siz; // SOSの後は、EOIとRSTくらいしか来ないので、SOSで止めても良いハズ if (true & mkr=0xda) { // SOSが来たら終了 fprint fout,"Stop analyze on SOS."$,; leave; } } procedure analyze_jpeg { // JPEGファイルサイズ var fsiz; fseek fin,-1; // -1:ファイルの終わりに移動 ftell fin,fsiz; fseek fin,0; // 0:ファイルの先頭に移動 // JPEGファイルを解析する var bdt; var fpos; fgetb fin,bdt; while (bdt!=EOF) { ftell fin,fpos; progress "JPEG解析中...",fpos*100/fsiz; if (bdt=0xff) { analyze_marker; } fgetb fin,bdt; } } // JPEGファイルを問いあわせる var rtn; macro fpath; gui openfile,rtn, "JPEGファイルを指定してください","",fpath; if (rtn=-1) { // Cancel leave; } // ファイルを開く var fin; fopen fin,$(fpath),"r"; if (fin<0) { errmsg "JPEGファイルが開けなかった"; leave; } var fout; fopen fout,$(fpath)".txt","w"; if (fout<0) { errmsg "出力ファイルが開けなかった"; leave; } // 解析 analyze_jpeg; // ファイルを閉じる fclose fin; fclose fout; }