ruby で tiff の解析をやってみる

Tiff ファイルの解析は ActionScript でやったことがあるので Ruby でもやっ
てみた.

Tiff の解析は他の画像形式に比べて面倒だけど,タグ (tiff の T) が取り出
せてしまえばあとはどうにでもできるだろう.ということで,今回はタグの一
覧を取り出すだけやってみる.

参考: CGファイル概説 第5章 第1節

コード

filepath = ARGV[0]

class IFDEntry
  attr_reader :tag
  attr_reader :type
  attr_reader :count_field
  attr_reader :data_field
  
  def initialize tag, type, count_field, data_field
    @tag = tag
    @type = type
    @count_field = count_field
    @data_field = data_field
  end

end


open(filepath) do |tifffile|
  tifffile.binmode

  byte_order = tifffile.read(2)
  if byte_order == "MM" then
    template_char_16 = "n"
    template_char_32 = "N"
  else
    template_char_16 = "v"
    template_char_32 = "V"
  end
  version_number = tifffile.read(2).unpack(template_char_16)[0]
  ifd_pointer = tifffile.read(4).unpack(template_char_32)[0]

  tifffile.pos = ifd_pointer
  entry_count = tifffile.read(2).unpack(template_char_16)[0]

  ifd_entries = []
  1.upto(entry_count) do
    tag = tifffile.read(2).unpack(template_char_16)[0]
    type = tifffile.read(2).unpack(template_char_16)[0]
    count_field = tifffile.read(4).unpack(template_char_32)[0]
    data_field = tifffile.read(4).unpack(template_char_32)[0]
    ifd_entries << IFDEntry.new(tag, type, count_field, data_field)
  end


  puts "Byte Order: " + byte_order.to_s
  puts "Version Number: " + version_number.to_s
  puts "IDF Pointer: " + ifd_pointer.to_s
  puts "Entry Count: " + entry_count.to_s

  ifd_entries.each do |entry|
    p entry
  end
end

実行

環境:
OS: Mac OS X (10.5.6)
ruby: 1.9.0


$ ruby tiffinfo.rb /Applications/Address\ Book.app/Contents/Resources/ABActionGear.tif
Byte Order: MM
Version Number: 42
IDF Pointer: 8
Entry Count: 24
#<IFDEntry:0x19ca1c @tag=254, @type=4, @count_field=1, @data_field=0>
#<IFDEntry:0x19c968 @tag=256, @type=3, @count_field=1, @data_field=983040>
#<IFDEntry:0x19c8b4 @tag=257, @type=3, @count_field=1, @data_field=983040>
#<IFDEntry:0x19c800 @tag=258, @type=3, @count_field=4, @data_field=302>
#<IFDEntry:0x19c74c @tag=259, @type=3, @count_field=1, @data_field=327680>
#<IFDEntry:0x19c698 @tag=262, @type=3, @count_field=1, @data_field=131072>
#<IFDEntry:0x19c5e4 @tag=273, @type=4, @count_field=1, @data_field=26312>
#<IFDEntry:0x19c530 @tag=274, @type=3, @count_field=1, @data_field=65536>
#<IFDEntry:0x19c47c @tag=277, @type=3, @count_field=1, @data_field=262144>
#<IFDEntry:0x19c3c8 @tag=278, @type=3, @count_field=1, @data_field=983040>
#<IFDEntry:0x19c314 @tag=279, @type=4, @count_field=1, @data_field=549>
#<IFDEntry:0x19c260 @tag=282, @type=5, @count_field=1, @data_field=310>
#<IFDEntry:0x19c1ac @tag=283, @type=5, @count_field=1, @data_field=318>
#<IFDEntry:0x19c0f8 @tag=284, @type=3, @count_field=1, @data_field=65536>
#<IFDEntry:0x19c044 @tag=296, @type=3, @count_field=1, @data_field=131072>
#<IFDEntry:0x19bf90 @tag=305, @type=2, @count_field=105, @data_field=326>
#<IFDEntry:0x19bedc @tag=306, @type=2, @count_field=20, @data_field=432>
#<IFDEntry:0x19be28 @tag=317, @type=3, @count_field=1, @data_field=131072>
#<IFDEntry:0x19bd74 @tag=338, @type=3, @count_field=1, @data_field=65536>
#<IFDEntry:0x19bcc0 @tag=700, @type=1, @count_field=15542, @data_field=452>
#<IFDEntry:0x19bc0c @tag=33723, @type=4, @count_field=2, @data_field=15994>
#<IFDEntry:0x19bb58 @tag=34377, @type=1, @count_field=10310, @data_field=16002>
#<IFDEntry:0x19baa4 @tag=34665, @type=4, @count_field=1, @data_field=26864>
#<IFDEntry:0x19b9f0 @tag=37724, @type=7, @count_field=1204, @data_field=26908>

できてるような気がする.
あとは IFDEntry オブジェクトと入力ファイルオブジェクトを適宜いじれば何でもできる.

まとめ

ActionScript よりもシンプルに書けた気がするのは二回目だからか?
コマンドラインで使うだけで Mac OS X なら,正直 tiffinfo で十分