忍者ブログ

GIF 圧縮ルーチン

ここにきてGIFの圧縮ルーチンを書くとは思わなかった。
8ビット専用だったりするし、ローカルパレットは使えないし、線形検索なんでおっそいし、メモリも結構食いそうだけども、一応動く物ができた。

作ったのも今さらだし、高速化する気持ちもメモリ効率をよくする気持ちも枯れて起きない。こまったもんだねぇ。

PR

2010/07/17 Programming Trackback(0) Comment(0)

Swingのrepaintとマルチスレッドとか

マルチスレッドで裏でごにょごにょしているものを作っていて、手元のマシン群では全くもってでなかったのだが、とあるところのとある人のマシンではなぜか画面の描画がちらちらっとするというお話があった。
画面はSwingで作っていて、方々みるが、ちらつきというと決まり文句しかでてこない。

だが問題はどうやらそこにはなくて、Swingだと元々ちらつかないよとか言われていたりしてこしゃくな!と思っていたところ(手元のマシンではないので再現しているかどうかチェックが難しかったというのもある)、しょうがねーなーと重いながらオフスクリーンバッファを用意して一瞬で書き換えてやる!とか意味不明なことを思っていました。

そのときぴらりんとひらめいたんですがマルチスレッドだから駄目なんじゃないかと。いや、実際は裏のスレッドはrepaintしか呼んでいなくて、多分大丈夫だと思っていたんですが、何のけなしにrepaintComponentにsynchronizedをつけたところぴたっと症状がおさまったようです。

のちのちに別の問題でInvokeLaterしないとだめとか、マルチスレッドにSwingは対応していないとか言われていましたが、repaintは大丈夫ということなんですがねぇ。意味がわかりませんでした。

 

2008/10/15 Programming Comment(0)

仕事での言語選択

なんかしらの変なものを作るかもしれない。というか直前まで怪しいソフト開発をしていた。
そいつはなぜかブラウザ上で動くことという条件が合ったのでJava Appletになったのだった。Java Web Startでもいいじゃないかと思いつつ。

次にあるかも知れないものは長期間起動しっぱなしなモノになるから長期間安定動作してほしい。となるとガベージコレクタのついたやつだと色々気楽だ。しかも数人でチームを組むのだが言っちゃあ何だが微妙に力量はばらばらだ。 

[つづきはこちら]

2008/10/04 Programming Comment(0)

lispでdat2html

書いてみた。

複雑な例外処理だとか怪しい処理はどうかわかりませんが、こういうフィルタ系の処理は関数型言語に向いていると思います。

そもそも関数というものがそういう物ものですからね。

Cだとサブルーチンも関数と呼びますが、Pascalだってfunctionとprocedureもありますが、このこたちは関数というよりもやはり手続きです。
古いBASICだと関数とステートメントは確かに別扱いで別なんですよね。

[つづきはこちら]

2008/09/21 Programming Comment(0)

Outlook の.msgを読み込む

とりあえずの成果物をhttp://higambana.ashigaru.jp/にアップしておいてみた。
まともに使用するにはまだ不足なのだがそれには訳がある。

その前にまずわかったこと、わかっていることについてまとめておく。
まず、.msgはほかのMS Officeのファイル形式と同様にStructured Storage((DocFileとかCOM stuctured storage OLE2 compound documentsとか構造化ストレージ呼ばれていたりします)という形式になっている。構造化ストレージのバイナリ構造は
http://sc.openoffice.org/compdocfileformat.pdf
が参考になる。
また、構造化ストレージは当然MSに多くの情報があるし、Windows上ではIStorageというものでサポートされている。
またOutlookの.msgに関しては
http://www.wotsit.org
に情報が存在する(完璧ではないが)。CPANにも
http://search.cpan.org/src/MVZ/Email-Outlook-Message-0.903/lib/Email/Outlook/Message.pm
というモジュールが存在した(ついさっき知った)。

これらのほかにわかったことといえば時刻の位置ぐらいのもので私はなんら活躍していないともいえる。


さて、Outlook ExpressとOutlookの間でインポートエクスポートしてどういうものが出てくるかというものを一番の参考にしていたのだが、そのとき、Outlookでインポートを選択した場合と、Outlook Expressでエクスポートを選択した場合とで出来上がる.msgは異なることがわかった。Outlookでインポートを選択した場合のほうがより詳細なファイルになるようだ。

大方の構造についてはwotsit.orgとcpanのモジュールを読めばわかりそうだが、問題になったのは日付だ。
日付は__substg1ではなく__properties_version1.0に格納されているようで、ここにはもっと多様な情報がありそうなのだ。
ちなみに日付は"40 00 39 00 06 00 00 00"の直後の8octetに入っている。リトルエンディアンなのでバイトオーダーを逆転させて読むこと。ちなみにFILETIME形式である。FILETIMEとUNIX timeの変換はMSのkb/167296 に存在する。今はD Langで作成しているのでd_timeに変換するが、その方法はFILETIMEからd_timeへの変換に載せてある。

Outlook側でインポートしたデータでは"03 00 DE 3F 06 00 00 00"の後にあるデータが元のエンコードのコードページを示しているのではないかとにらんでいるがこれは憶測である。
憶測ついでだが、この__properties_version1.0エントリー以下のデータは16オクテットセットで、始めの8オクテットがデータの識別子で、その後8オクテットがデータ本体ではないか考えている。サンプルが少なすぎてわからない部分が多すぎるので推測でのみ語っている。

__substg1.0_10090102 には見たところメールの本文が圧縮されて入っているようだが、ここにはコードページらしきものも書かれている。ここがデコードできればいいのかもしれないがここまでは……。

ともあれ、この程度で大方のデータは取得できる。ヘッダで重要なのはやはりFromやTo、Cc、Subject、Date等の項目で(Reply-toなんかも必要だろうがFromほど重要ではない。もっともとるのは簡単である)、ReceivedとかのSMTPリレーはデータ本体ほど重要ではないだろう(スパム判定なんかでは重要だが)。もっとも重要な本文と添付ファイルが取り出せるようになっていればそうそう困らないのではないだろうか。


蛇足だがThunderbirdではOutlookからインポートすると時刻がDOS Timeにでもしているのかずれていたり、メールアドレスがぶった切れたりすることが多々あった。あまりお勧めできるとはいいがたかった。ちなみにバージョンは2.0.0.9であった。

----2008/03/16 追記
SenderとReply-Toヘッダフィールドについて
Senderは0C1Aに表示名、0C1Fにアドレスが入る。Fromと同等の扱いでよさそう。
一方Reply-Toだが、なぜか表示名は0050にあるのだがアドレスがない。
ただし、004Fに表示名、プロトコル、アドレスが含まれているようなのでとりあえずこれを使う。
01 00 00 00 6C 00 00 00  68 00 00 00 00 00 00 00
81 2B 1F A4 BE A3 10 19  9D 6E 00 DD 01 0F 54 02
00 00 01 80
という羅列の後に表示名、プロトコル、アドレスの順にNull文字区切りで格納されているようだ。でもたぶん頭のほうは変わるかな。特に6Cと68は絶対変わると思う。試せっていう話ですが。
ちなみにFromとSenderも似たような部分があってそれぞれ0041、0C19にある。
こちらは
00 00 00 00 81 2B 1F A4  BE A3 10 19 9D 6E 00 DD
01 0F 54 02 00 00 01 80
こうなっていた。たぶんこのあたりは全く変わるんじゃないかと思うけども、00 00 00 00 以降が一致しているので、まあそんなもんなんだろうと思うことにする。とりあえず、実装としては00 00 00 00を検出するまでスルーして、さらにその後20オクテットぶっ飛ばすようにしてみた。
ちなみにここは0102という型からもわかるように文字列型ではない。どうやらUTF-16固定のような気がするのでそのようにしてしまう。

実装は汚いし、本当に解決できているか怪しいがこれで大体ほしいヘッダは集まったかな(日付はローカルタイムにしていいみたいだし)。
後はエンコードをどうするかが難関。圧縮されているっぽい、10090102の頭の方にコードページっぽいところがあるのでこいつを使わせてもらうことにしてもいいかも。でもShift_JIS(というかCP932)だったらiso-2022-jpとするとかいう対応はどうすればいいんだろ?
いっそすべてUTF-8でやってしまうのも楽でいいんだが。

現在のところは以上。

2008/03/02 Programming Comment(0)

FILETIMEからd_timeへの変換

http://support.microsoft.com/kb/167296 に、Unix Time(time_t)からFILETIMEへの変換方法が載っています。
d_timeは1970年1月1日からの経過時間で、Unix Timeとは始点は同様ですが、粒度が違います。

wftがFILETIMEを64ビット整数に格納したとして、オーバーフローを考慮しないとすれば、

d_time Win32FILETIME2d_time(ulong wft)
{
    wft -= 116444736000000000;    // 1970年までおろす。
    return wft * TicksPerSecond / 10000000;
}
という変換関数が書き下せます。Phobos内にはFILETIMEをd_timeに変換する部分があるのですが一度SYSTEMTIMEにしてから変換をかけています。理論上、FILETIMEからSYSTEMTIMEにするとミリ秒に丸められちゃうんですよね。そんな細かく使っているか確かめてもいませんし、神経質になるほどの粒度ではないんですが。

2008/03/01 Programming Comment(0)

Turbo Delphiとか

いやー、Delphiって本当に(以下略
なんにせよ、なにかしらのコンパイラとかインタプリタとかのプログラム用の言語(って言わなきゃなんていえばいいのか)ツールは欠かせません。Rubyとか言ってると大変な人扱いされることもありますがPerlもいいですし(なんといっても枯れた使いやすさがある)、Pythonだっていいです。DelphiじゃなくてCとかC++だってDだって好きですしね。JavaだってC#だっていまとなってはそれなりに動いてくれますし好きな部類に入ります。

で、なんでDelphiいってるかというとネイティブで、かつRADだから。しかもTurbo DelphiはExplorerなら無償で使用できます。MSがなんやらのExpressをだしていますが、Borland陣営はExplorerという名称で似たことをやっているわけです。C#は消えましたが。

C/C++ならMSのコンパイラが好きなんですがRADで、ネイティブなものというとやはりDelphi。Cじゃないので嫌がる人もいますがやっぱりDelphi。C/C++じゃないと先行きが心配とか使いまわしが……という意見やら思想もあるのですがそもそもRADツールでそんなことはあまり気にしないほうがいいのではと思う今日この頃。確かに不安はありますが、PascalならほぼストレートにCにトランスコードできますし。あ、いやC++に。Object Pascal(≒Delphi Language)はどうよ? というと、これも大体C++にできるわけです。面倒な部分もありますけどね。というわけで、それよりも自分が使いやすいものを使いたいように使う。そのためには多少のお布施はいとわない。とこういうわけです。はい。Delphi6 personalは爆発的にはやったけど、その後の対応のせいか、先行きの不透明さのせいか今ひとつはやっていないのが残念ですね。MSの戦略かもしれませんけど日本語がきっかり通る言語類ってそんなに数が豊富にないので(昔よりはいいのはわかっていますが)がんばってほしいですね。

2008/02/04 Programming Comment(0)

Excelに高速っぽくVBAとかOLEとかでデータを入れる

rubyってすばらしいです。何がすばらしいかは相対論なのでさておくとして、とあるデータをほげほげっとするとしてたときにrubyとかperlとか、まあなんかそのあたりのものを使えると楽です。CだとかC++だとかJavaだとかまあなんでもいいんですがそっち系統のものだと割りに面倒なことが楽チンにできたりするのですね。そんなに変わらない処理もあったりしますが。

で、まあさておいて、VBAとかはVB6時代のものがベースだったりして(VBSも)、BASICとしてみても気持ち悪いし、まじめな言語としても微妙です。いや、そんなに悪くはないですが。
標準のデータ構造が微妙で、Collectionのお世話になりっぱなしなVBAは捨てて、結局VBAもOLEでごりごりやるのと変わらないので特別な場合は別にして外部で好きな言語でやってもいいと思うんですね。やらなくてもいいんですが。


という前置きはいいとしてExcelにデータを追加するときに
ScreenUpdating = false
というのはよくやりますが、データをセルに入れていくところがこれまた遅いので高速にしたいわけです。
外部のあれでやるならCSVにでもして読み込めいわれそうですが(間違いなく高速ですし環境にも依存しないすばらしい方策です)、16進数だったりする文字列を文字列として扱いたいときはこまりものです。あの子は勝手に数値データとして扱ってくれたり浮動小数点数として扱ってくれたりします。

そんなときには
cells.Style.NumberFormat = "@"
とでもしてやったセルにデータを入れるしかありません。
一個一個データを入れるのが筋かもしれませんがそうすると遅くて泣きそうになるのでセルを選択してデータを配列で渡します。

sheet.Range(省略).Select
Selection.Value = 配列

配列データが一次元だと一行のデータを入れることになりますが、二次元配列にして複数行を選択すれば一気に複数レコードのデータを投げることもできるようです(Excel 2003で確認)。

はぁ。なんでみんなExcel好きなんですかね? なぞの挙動が多くて安心して使えないんですが。

2008/01/27 Programming Comment(0)

カテゴリー
 
 
 
最新記事
 
(10/10)
(08/05)
(07/29)
(06/16)
(06/13)
 
 
ブログ内検索
 
 
 
カレンダー
 
09 2017/10 11
S M T W T F S
1 2 3 4 5 6 7
8 9 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
 
 
アーカイブ
 
 
 
最新TB
 
 
 
最新CM
 
 
 
リンク
 
 
 
Feed
 
 
 
注意点
 

英字のみのコメントは拒否しています。スパムの排除のためご理解をお願いいたします。(でも結構スルーされてしまいます。たまに掃除していますがご容赦のほどを。)

 
 
カウンター
 
 
 
アクセス解析