.aco から色のデータを HTML カラーコードにして抽出する

extract_colorcodes_from_aco.rb

binary_file = 'test.aco'
color_num   = 0
colorcodes  = []

open(binary_file, 'rb') {|f|
  f.getc; f.getc # 0001 を読み飛ばす
  color_num = 256 * f.getc + f.getc # 色数
  p color_num

  until f.eof?
    colorcode  = ""

    f.getc; f.getc # 0000 を読み飛ばす
    3.times do
      colorcode << "%02x" % f.getc; f.getc
    end
    f.getc; f.getc # 0000 を読み飛ばす
    colorcodes << colorcode
  end
}

p colorcodes.join(' ')

実行結果

ruby -w extract_colorcodes_from_aco.rb
33
"dedfde c6c7c6 9ca2a5 63696b 313431 212421 ffcfce f7aaad e74d52 de3039 b58a73 9c6142 732800 4a2008 ffdfd6 ffd3c6 ffc3ad ffb29c ffef94 ffdf4a f7b28c ef8242 de7d4a def3ef addbce 7bbead 316d63 295d52 d6ebff 8ccbef 7b96ce b5aed6 7b75b5"

aco のフォーマットについて

ググったらリバースエンジニアリングしてる人の資料とか公式っぽい資料とか
英語のソースが2つほど見つかったので最初はそれを読んでいた。
でも僕がいじりたかった SAI が SST で読み書きするときに使う aco
それ手元にあったので、結局は自分で aco の中身を眺めて判断した。
思っていたほどややこしいものでもなかったので最初からそうしてればよかったなぁ。


以下具体例を用いつつ簡単に説明。
今回使った「test.aco」をバイナリエディタなどで見るとこんな感じになっている。
(これはファイルの先頭部分だけで後ろの方は省略してある。)

0001 0021 0000 de00 df00 de00 0000 0000
c600 c700 c600 0000 0000 9c00 a200 a500
0000 0000 6300 6900 6b00 0000 0000 3100
3400 3100 0000 0000 2100 2400 2100 0000
0000 ff00 cf00 ce00 0000 

最初の「0001 0021」っていうのがこのファイルに書かれている色の数を表している。
「0001」は目印みたいなものでこれに続く「0021」が色の数。
「0021」は16進数なので10進数に直すと33。
だからこのファイルに書かれているデータは33色分。


そしてそれ以降の数字は「0000 rrrr gggg bbbb 0000」で1色を表していて
それがファイルの終わりまでずっと続いている。
「0000」はたぶんセパレータ。「0001」といっしょで目印みたいなもの。
大事なのは挟まれている「rrrr gggg bbbb」でこれらがそれぞれ赤、緑、青の値になっている。
各色ごとに4ビットずつ用意されてるのだけど、とりあえずは手前の2ビットだけでもいいみたい。
(後ろの2ビットはよく分かってないので割愛。)
だから、「de00 df00 de00」だったら赤が「de」で緑が「df」で青が「de」。
つまり、「0000 de00 df00 de00 0000」を HTML カラーコードにすると「dedfde」になる。
「test.aco」の色データを順番にカラーコードに直していくと、
dedfde、c6c7c6、9ca2a5 … となり、これは前述の実行結果のものと一致する。