# -*- coding: Windows-31J -*- =begin == Susieプラグイン用 ライブラリ susie.rb 書いた人:nyasu3w@users.sourceforge.net 書いた日:2009/01/17 SusiePluginクラスが提供されています。 Susieのプラグインを使って、画像を読み込んだり調べたりします。 各メソッドの詳細はsusieのSPI_API.TXTを見てください。 === Susieとは Susieの部屋: http://www.digitalpad.co.jp/~takechin/ で配布されている、さまざまなフォーマットの画像を閲覧できるソフトです。 === 利用例(vruby) require 'susie' require 'vr/vruby' class MyForm < VRForm include VRDrawable def construct # プラグインを探す spifiles = SusiePlugin.find_plugin("02.jpg") # 最初に見つかったプラグインのオブジェクトを作る spi = SusiePlugin.new(spifiles[0]) # 画像に変換する @bmp = SWin::Bitmap.createBitmap(*spi.getPictureFromFile("02.jpg")) end def self_paint # ウインドウに書く drawBitmap @bmp if @bmp end end VRLocalScreen.start(MyForm) == クラスメソッド --- find_plugin(filename, plugin_dir=SUSIE_PLUGIN_DIR) filenameを画像ファイルとして、対応するプラグインファイルのパスが 入った配列を返します。 第二引数にはプラグインの存在するディレクトリを渡します。省略すると レジストリからディレクトリを探しますが、エントリがない場合もあるかも。 --- new(spifile) spifileをプラグインのパスとして、SusiePluginのオブジェクトを作成します。 == メソッド --- getPluginInfo(n) プラグインの情報を返します。 nが0でプラグインAPIバージョン、1でプラグイン名、バージョンなど、 以降、2nが代表的な拡張子、(2n+1)でファイル形式名の組が続きます。 ここで扱うプラグインはn=0の時00INが返るものを 想定しています。 --- isSupported(filename,content) 画像に、プラグインが対応しているかどうかを調べ、対応していればtrueを返します。 filenameに画像のファイル名を、contentに、ファイルの中身を文字列として 2Kbytes以上渡します。 --- getPictureInfoFromFile(filename,offset=0) 画像ファイルに関する情報を得ます。 filenameに画像ファイル名、offsetは読み飛ばすバイト数を入れます。 情報の入った配列を返します。 [left,top,width,height,x_density,y_density,colorDepth, hInfo] --- getPictureInfo(content,contentsize=content.size) 画像ファイル名の代わりに、ファイルの中身をcontentに文字列で渡す以外は、 getPictureInfoFromFileと同じです。 --- getPictureFromFile(filename,offset=0) 画像を展開します。filenameに画像ファイル名、offsetは読み飛ばすバイト数を 渡します。BITMAPINFO構造体の入った文字列とビットマップデータの入った文字列 を配列にして返します。[bmpinfo,bmpdata] 進捗のコールバックはありません。 --- getPicture(content,contentsize=content.size) 画像ファイル名の代わりに、ファイルの中身をcontentに文字列で渡す以外は、 getPictureFromFileと同じです。 =end require 'Win32API' require 'win32/registry' class SusiePlugin MINIMUM_CONTENT=0x2000 def self.find_plugin(filename,plugin_dir=nil) plugin_dir = get_registry_plugindir unless plugin_dir content = File.read(filename,MINIMUM_CONTENT) plugins = [] Dir.glob(plugin_dir.gsub(/\\/,'/')+"/*.[Ss][Pp][Ii]") do |plg| r = Win32API.new(plg,"IsSupported","PP","I").call(filename,content) plugins.push(plg) if r!=0 end plugins end def getPluginInfo(n) size=80 buf = "\0"*size len = @spiinfofunc.call(n.to_i,buf,size) return (if len>0 then buf[0,len] else nil end) end def isSupported(filename,content) len = content.length if len < MINIMUM_CONTENT then content << "\0" * (MINIMUM_CONTENT-len) end (0 != Win32API.new(@spifile,"IsSupported","PP","I").call(filename,content)) end PictureInfoStr = "llllsssl" def getPictureInfoFromFile(filename,offset=0) ar = [0,0,0,0,0,0,0,0].pack(PictureInfoStr) r=Win32API.new(@spifile,"GetPictureInfo","PIIP","I").call( filename,offset,0,ar) if r==0 then ar.unpack(PictureInfoStr) else raise "GetPictureInfo() failed" end end def getPictureInfo(content,contentsize=content.size) ar = [0,0,0,0,0,0,0,0].pack(PictureInfoStr) r=Win32API.new(@spifile,"GetPictureInfo","PIIP","I").call( content,contentsize,1,ar) if r==0 then ar.unpack(PictureInfoStr) else raise "GetPictureInfo() failed" end end def getPictureFromFile(filename,offset=0) hbmpinfo=[0].pack("L") hbmpdata=[0].pack("L") r = Win32API.new(@spifile,"GetPicture","PIIPPII","I").call( filename,offset,0,hbmpinfo,hbmpdata,0,0) if r!=0 then raise "GetPicture() failed" end bmpinfo = getLocalMemAndFree(hbmpinfo.unpack("L")[0]) bmpdata = getLocalMemAndFree(hbmpdata.unpack("L")[0]) [bmpinfo,bmpdata] end def getPicture(content,contentsize=content.size) hbmpinfo=[0].pack("L") hbmpdata=[0].pack("L") r = Win32API.new(@spifile,"GetPicture","PIIPPII","I").call( content,contentsize,1,hbmpinfo,hbmpdata,0,0) if r!=0 then raise "GetPicture() failed" end bmpinfo = getLocalMemAndFree(hbmpinfo.unpack("L")[0]) bmpdata = getLocalMemAndFree(hbmpdata.unpack("L")[0]) [bmpinfo,bmpdata] end #----------------------- private def initialize(spifile) @spifile=spifile # keep loaded @spiinfofunc = Win32API.new(@spifile,"GetPluginInfo","IPI","I") end def self.get_registry_plugindir dir = "" Win32::Registry::HKEY_CURRENT_USER.open( 'Software\Takechin\Susie\Plug-in') do |reg| dir=reg['Path'] end dir end LocalFree = Win32API.new("kernel32","LocalFree","I","I") LocalLock = Win32API.new("kernel32","LocalLock","I","I") LocalUnlock = Win32API.new("kernel32","LocalUnlock","I","I") LocalSize = Win32API.new("kernel32","LocalSize","I","I") RtlMoveMemoryPI = Win32API.new("kernel32","RtlMoveMemory","PII","I") def getLocalMemAndFree(handle) pointer = LocalLock.call(handle) size = LocalSize.call(handle) buffer="\0" * size RtlMoveMemoryPI.call(buffer,pointer,size) LocalUnlock.call(handle) LocalFree.call(handle) buffer end end