特に理由もなく一年以上放置していましたが、特に理由もなく再開します。
最近、仮想端末をiTerm2にしたので、xterm-256使えるぞと思って色々遊んでいました。(*OSX標準のターミナルもいつの間にかxterm-256対応していた)
Unicodeには点字を表現するための文字群があり、2x3の点字64種類とそれを含む2x4の点字256種類で構成されています。 これはUnicode中で自由に制御できる最も解像度の高い文字群ではないかと思い、xterm-256と合わせて利用してみることにしました。
# ちなみにこんなのです
⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿
Step 1
まずは点字のみで、二値画像を表現してみます。 ちょうど新しい職場でPythonを使い始める時期だったのでPythonで、二値画像としては手頃なマンデルブロ集合を使います。
ポイントはWikipediaにもありますが、2x3の点字が最初のほうに固まっているので、ビットを入れ替える必要があるところとマンデルブロの綴りくらいでしょうか。
Step 2
Pythonにも慣れてきたので次はいよいよxterm-256を使いますが、いきなりカラーは難しそうなのでグレイスケールを使います。
The 256 color mode of xtermによれば、xterm-256はシステムカラー16色、6階調RGBの216色、グレイスケール24段階の計256色で構成されており、 以下のシーケンスで前景色、背景色が指定できます。(ここだけRubyです)
print "\e[38;5;#{color}m" # 前景色
print "\e[48;5;#{color}m" # 背景色
# グラデーションがでます
$ ruby -e '24.times{|i|print"\e[48;5;#{232+i}m "};puts'
そうしてできあがったのが以下のコードです。
基本的には、切り出された2x4pixelsに対して最も暗い色と明るい色を前景色/背景色に選び、各pixelをどちらかに振り分けるだけなんですが、
- 誤差拡散法
- なるべく前景色/背景色が同じにならないようにする
- ガンマ調整(のようなもの)
といった工夫によりかなり画質を向上させています。 興味のある方はコードを弄って、どれくらい画質に影響を与えているか見てみると楽しいかもしれません。
Step 3
カラー対応といいたい所ですが、3次元から1次元へ削減を行わないといけなかったり、人間の色覚モデルを考慮するのが面倒そうだったりしてまだやってないです。
関西闇Ruby会議で発表しました。
内容は最近使う機会の増えたruby-ffi(フィッフィ)の紹介。 その時のスライドです。
ちょっとまとめきれなくて最後のほうにごちゃごちゃと書いてしまっていますが、C/Ruby間で独自の型変換を作れるとあったので試しにVALUE型をRubyのオブジェクトに変換するffi-rubyというのを作ってみました。 実用的なかおりがするけどあんまり使い途ない。
VALUE型の変換これであってるのかなぁ。簡単な恒等性のテストにはパスしてるみたいだけど。
@ikegami__さんのFrama-Cを使った実験が面白そうなので試してみた。
試験環境はMacBookAir/Mac OS X Lion/ruby192
インストール
$ brew install ocaml
$ wget http://frama-c.com/download/frama-c-Nitrogen-20111001.tar.gz
$ tar zxf frama-c-Nitrogen-20111001.tar.gz
$ cd frama-c-Nitrogen-20111001
$ ./configure --prefix=...
$ make
$ make install
使ってみる
Rubyのソースツリーに移動する。
$ cd ruby
$ ./configure
記事を参考に、.ext/include/ARCH_NAME/ruby/config.h
に以下の行を追加。
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
解析対象ファイルの一覧を作っておく。
$ vi mainobj
array.c bignum.c class.c compar.c complex.c dir.c dln_find.c enum.c enumerator.c error.c eval.c load.c proc.c file.c gc.c hash.c inits.c io.c marshal.c math.c node.c numeric.c object.c pack.c parse.c process.c random.c range.c rational.c re.c regcomp.c regenc.c regerror.c regexec.c regparse.c regsyntax.c ruby.c safe.c signal.c sprintf.c st.c strftime.c string.c struct.c time.c transcode.c util.c variable.c compile.c debug.c iseq.c vm.c vm_dump.c thread.c cont.c
一覧は、common.mk
中のCOMMONOBJS
を参考にしている。
Frama-C Nitrogen 20111001 で ruby-1.9.2-p290 を検査するときにどうにもならなさそうな事であげられているファイルのいくつかは、直接コンパイルされることを想定して書かれていないので失敗するようだ。
解析開始
$ frama-c \
-cpp-extra-args="-U__BLOCKS__ -DRUBY_EXPORT -I./.ext/include/ARCH_NAME -Iinclude" \
-machdep x86_64 \
-save ruby.session \
`cat mainobj`
-U__BLOCKS__
はSnowLeopardから導入されたBlocks(Cの文法を拡張している)を無効にするため。これを無効にしないとparseが失敗する。
-machdep x86_64
はARCH_NAMEにあわせたものを$ frama-c -machdep help
の結果から選ぶ。
$ frame-c -load ruby.session -metrics
...(ry)...
[metrics] Syntactic metrics
-----------------
** Defined functions (6297):
...(ry)...
** Undefined functions (297):
...(ry)...
** Potential entry points (1694):
...(ry)...
SLOC: 144947
Number of if statements: 25635
Number of assignments: 40691
Number of loops: 3651
Number of calls: 31176
Number of gotos: 7496
Number of pointer access: 50736
$ frame-c -load ruby.session -users -main rb_ary_new
...(ry)...
[users] ====== DISPLAYING USERS ======
ary_alloc: rb_newobj
ary_new: rb_newobj ary_alloc
rb_ary_new2: rb_newobj ary_alloc ary_new
rb_ary_new: rb_newobj rb_ary_new2 ary_alloc ary_new
====== END OF USERS ==========
参考:
MacBookPro壊れてLinux使ってた時にGUIのものしか見当たらなかったので。
名前も未定です。
Rubyリファレンスマニュアルのchmは文字コード変なので悲しい。