These pages are written by only Japanese.

Welcom to My Diary.com
最新の日記タイトル一覧カテゴリ別タイトル一覧トップへ戻る〜

おはようございます♪ 現在は3月29日(金)5時26分。 外が白んでくる時間です。


hns - 日記自動生成システム - Version 2.19.5 (色々 Fixed)

先月 2008年09月 来月
01 02 03 04 05 6
07 08 09 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Namazu for hns による簡易全文検索です。
詳細は 詳細指定/ヘルプをご参照下さい。
検索式:

2008年09月01日(月)

テスト用 PNG ファイル生成

PNG 画像の処理に色々と問題があるので、 テストを綿密にやろうとテスト用の PNG ファイルを作ってみました。
パレット形式かビットマップ形式か、何色使うかといったパターンを 手で作るのはやってられないので、プログラムで生成する事にします。

png_test.php:

GD を使うと楽ですね。
<?php

$width  = 8;
$height = 8;

$im = imagecreatetruecolor($width, $height); /* bitmap */
// $im = imagecreate($width, $height);          /* palette */

$colors = array();
$colors []= imagecolorallocate($im, 255, 0, 0); // red
$colors []= imagecolorallocate($im, 0, 255, 0); // green
$colors []= imagecolorallocate($im, 0, 0, 255); // blue
$colors []= imagecolorallocate($im, 255,255,0); // yellow

for ($y=0 ; $y < $height ; $y++) {
    for ($x=0 ; $x < $width ; $x++) {
        $i = ($x + $y * $width) % 4;
        imagesetpixel($im, $x, $y, $colors[$i]);
    }
}

header("Content-type: image/png");
imagepng($im);

png_dump.c:

とりあえず、何も考えずに dump してみる。
% ./a.out  ~/lang/php/16x16palette.png
png_filename=/home/yoya/lang/php/16x16palette.png
png_buff.data_len=94
(width, height)=(8,8) bpp=2 color_type=3(PALETTE) palette_num=4
y=0: 1b 1b 24 00 80 11 24 00
y=1: 1b 1b 00 00 00 00 00 00
y=2: 1b 1b 00 00 00 00 00 00
y=3: 1b 1b 00 00 00 00 00 00
y=4: 1b 1b 00 00 00 00 00 00
y=5: 1b 1b 00 00 00 00 00 00
y=6: 1b 1b 00 00 00 00 00 00
y=7: 1b 1b 00 00 00 00 00 00
ナルホド。
1b = 00011011 = 00 01 10 11 = 0 1 2 3
って事か。
吸い出したイメージ配列は bpp の bit width で並んでるようです。

png_dump.c 修正版:

ビット処理を書くのが面倒なので、 swfed で作った bitstream.c を使いまわしました。
for (y=0; y < png_height; y++) {
    unsigned char *linedata = image_data[y];
    bitstream_t *bs = bitstream_open();
    bitstream_input(bs, linedata, png_get_rowbytes(png_ptr, png_info));
    printf("y=%lu: ", y);
    for (x=0; x < png_width; x++) {
        int colorindex = bitstream_getbits(bs, bpp);
        printf("%02x  ", colorindex);
    }
    bitstream_close(bs);
    printf("\n");
}
実行結果
% ./a.out 16x16palette.png
png_filename=16x16palette.png
png_buff.data_len=94
(width, height)=(8,8) bpp=2 color_type=3(PALETTE) palette_num=4
y=0: 00  01  02  03  00  01  02  03
y=1: 00  01  02  03  00  01  02  03
y=2: 00  01  02  03  00  01  02  03
y=3: 00  01  02  03  00  01  02  03
y=4: 00  01  02  03  00  01  02  03
y=5: 00  01  02  03  00  01  02  03
y=6: 00  01  02  03  00  01  02  03
y=7: 00  01  02  03  00  01  02  03
よし、完璧。(゜∇゜) コンパイル方法
% gcc -Wall -W png_dump.c -lpng bitstream.c
使い方は上の通り。

追記 (2011/12/19):

「imagemagick palette png」で検索された方はこちらも参考にどうぞ。

2008年09月02日(火)

山登り断念

久しぶりなのでリハビリ兼ねて、大山に登ってみたのですが、 黒い雲が山を覆いだしたので、道の真ん中辺りで断念しました。 残念無念。
中腹の神社が工事中でしたね。

[swfed] 透明度無しパレット形式画像処理の不具合修正

透明度無しのパレット画像(いわゆる色index方式)の入っている SWF ファイルを 読み込めない不具合があるので、その対応をしました。

問題:

% php sample/swfdump.phps bitmap.swf
magic=FWS  version=4  file_length=209
rect=(0, 0)-(240, 350) (f_size=14)
frame_rate=12.0  frame_count=1
[0] tag=SetBackgroundColor(9)  length=3
[1] tag=DefineBitsLossless(20)  length=30
swf_tag_lossless_create_detail: indices_len != origsize - 4 * swf_tag_lossless->colormap_count at line(62)
can't create tag detail (tag=20)
swf_tag_lossless_print_detail: detail == NULL
[2] tag=DefineBitsLossless(20)  length=29
        image_id=2  format=5  width=8  height=8
        xrgb bitmap exists
[3] tag=DefineShape2(22)  length=95
[4] tag=PlaceObject2(26)  length=6
[5] tag=ShowFrame(1)
[6] tag=End(0)

原因:

color を 4 byte 決めうちで処理してましたが、以下のように場合によって変わります。
format 3 (palette 形式)
Lossless: 1color 3byte (rgb)
Lossless2: 1color 4byte (rgba)
format 5 (bitmap 形式)
Lossless: 1pixel 4byte (xrgb) x は padding
Lossless: 1pixel 4byte (argb)
というわけで修正。

修正:

SWF Lossless 内の colormap のフィールド長を計算する際に、 以前は 4 決め打ちだったのを、 format=3 で且つ、tag=20(Lossless)の場合は 3 で処理するように修正。

確認:

% php sample/swfdump.phps bitmap.swf
magic=FWS  version=4  file_length=209
rect=(0, 0)-(240, 350) (f_size=14)
frame_rate=12.0  frame_count=1
[0] tag=SetBackgroundColor(9)  length=3
[1] tag=DefineBitsLossless(20)  length=30
        image_id=1  format=3  width=8  height=8
        colormap_count=4  rgb colormap exists  indices exists
[2] tag=DefineBitsLossless(20)  length=29
        image_id=2  format=5  width=8  height=8
        xrgb bitmap exists
[3] tag=DefineShape2(22)  length=95
[4] tag=PlaceObject2(26)  length=6
[5] tag=ShowFrame(1)
[6] tag=End(0)
% php sample/swfgetpngdata.phps bitmap.swf 1 > 1.png
% php sample/swfgetpngdata.phps bitmap.swf 2 > 2.png
% png_dump 1.png
png_filename=1.png
png_buff.data_len=119
(width, height)=(8,8) bpp=8 color_type=3(PALETTE) palette_num=4
y=0: 00  01  02  03  00  01  02  03
y=1: 00  01  02  03  00  01  02  03
y=2: 00  01  02  03  00  01  02  03
y=3: 00  01  02  03  00  01  02  03
y=4: 00  01  02  03  00  01  02  03
y=5: 00  01  02  03  00  01  02  03
y=6: 00  01  02  03  00  01  02  03
y=7: 00  01  02  03  00  01  02  03
% png_dump 2.png
png_filename=2.png
png_buff.data_len=103
(width, height)=(8,8) bpp=8 color_type=2(RGB)
y=0: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=1: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=2: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=3: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=4: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=5: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=6: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
y=7: ff0000  00ff00  0000ff  ffff00  ff0000  00ff00  0000ff  ffff00
問題なし。
吸い出す時に処理をサボる為に bpp = 8 決め打ちにしてるけど、 時間見つけて bpp そのまま吸いだせるように修正しとこう。
あと、palette 形式を差し替える時、bitmap で入っちゃうので、 これは早めに対応しとこう… (焦

追記 (2009/10/23):

「swf lossless 2 RGBA」で検索して辿りついた方がいらっしゃったので。

2008年09月03日(水)

mp3 header 抽出

以下のページを参考に mp3 header の抽出を試みました。 試験対象の MP3 が DefineSound に入っていた時の情報は以下の通り。
[4] tag=DefineSound(14)  length=2505
        sound_id=1
        format=2(MP3) rate=1 is_16bits=1 is_stereo=0 samples_count=11019
        sound_data(length=2498)

実験コード:

実験結果:

mp3_filename=../game-1.mp3
mp3_data_len=2498
sync_word=0x7ff
version=0
layer=1
no_protection=1
bit_rate=2
sample_rate=0
padding=0
reserved=0
channel_mode=3
mode_extension=0
copyright=0
original=0
emphasis=0
----
sync_word=0x7ff
version=2
layer=2
	<略>
試しに sync word を scan してみたところ、 一個目の header は正しく抽出されてそう *1 ですが、2つ目以降はボロボロ。
header の後ろはある程度 skip する必要があるらしいので、 一応想定通りではあります。さて…

skip 処理を入れてみた:

試しに header の後ろを何 byte か skip した所、 いい感じに header が取れました。
while (mp3_dump_frame(bs)) {
//    bitstream_incrpos(bs, 97, 0);  // NG
    bitstream_incrpos(bs, 98, 0); // OK
//    bitstream_incrpos(bs, 100, 0); // OK
}
実行結果
% ./a.out  ../game-1.mp3 | grep version=0 | wc
bitstream_getbit: bs->data_len(2498) <= bs->byte_offset(2498)
     24      24     240
bitstream_getbit の警告は bitstream.c 側の問題なのでご容赦を。(⊃д⊂)
この 98 というのは仮の数字で、実際は header の内容から frame size を算出して (frame size - header size 分だけ) skip する必要があるのですが、 mpglib のコード(lame/mpglib/common.c)を見ると、
witch(fr->lay)

 case 1:
           fr->framesize  = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
           fr->framesize /= freqs[fr->sampling_frequency];
           fr->framesize  = ((fr->framesize+fr->padding)<<2)-4;
           fr->down_sample=0;
           fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample);
   break;

 case 2:
           fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
           fr->framesize /= freqs[fr->sampling_frequency];
           fr->framesize += fr->padding - 4;
           fr->down_sample=0;
           fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample);
   break;
      case 3:
	<略>
なんだか、面倒そうなのでやっぱり自前はやめて mpglib を利用する事にします。(´Д`;)

*1: Winamp のファイル情報の表示内容と一致する。

2008年09月04日(木)

mp3 header 抽出 (2)

煮詰まったので、こんな時は人様のコードをカンニング。:-)

mpglib のヘッダ:

struct buf {
        unsigned char *pnt;
        long size;
        long pos;
        struct buf *next;
        struct buf *prev;
};

struct framebuf {
        struct buf *buf;
        long pos;
        struct frame *next;
        struct frame *prev;
};
あれ?
typedef struct mpstr_tag {
	<略>
    struct frame fr; /* holds the parameters decoded from the header */

むむむ…
struct frame {
    int stereo;
    int jsbound;
    int single;
	<略>
    int bitrate_index;
	<略>
    int framesize; /* computed framesize */
まさしく欲しいデータ構造がそのまま定義されてます。
という訳で、自前で頑張らない方がいいかも。
問題は mpglib は lame の内部で使われる事があっても、 一般には独立してインストールされるとは限らないのが難点。
という訳で、(mpglib を内包してる) lame を使ってみました。
% gcc lame_test.c -L/usr/local/lib -lmp3lame
$ env LD_LIBRARY_PATH=/usr/local/lib ./a.out  game-1.mp3
何となく使い方は分かってきたけど、残念ながら frame header chain を作る API が見つからず。うーむ。

ProjectXI を動かしてみた

FFXI エミュ鯖の実装とバイナリが公開されていたので 試しに動かしてみた。(今月遊ぶ気なかったけど、これだけの為に課金…)

動かす手順:

サーバ側。
  • MySQL を用意する (面倒なので Linux 上で動かしている MySQL に居候)
  • MySQL 上に pxi アカウントを作成 (別のユーザ名でも OK)
  • pxidb を作成する
    sql> CREATE DATABASE pxidb
    
  • ProjectXI\bin\server\misc\pxidb.zip の中にある sql 文を流し込む
    % cat pxidb.sql | mysql -h <秘密のIP> pxidb -u pxi -p
    
  • ProjectXI\bin\server\pxi.ini をいじる
    • 別ホストの MySQL も指定できる
    • pxi 以外のユーザ名をで MySQL にアクセスするなら、設定変更
    • pxi ユーザのパスワードも指定できる (デフォのままだと危険なので要変更)
  • ProjectXI\bin\server\pXI-Server0.6.1.exe を起動
  • ProjectXI\bin\client\pXi-Clientv.exe を起動してアカウント作成
クライアント側
  • ProjectXI\bin\client\pXi-Clientv.exe でログイン (必須?)
  • C:\Windows\system32\drivers\hosts に以下の設定を追記
    127.0.0.1  ffxi00.pol.com
    
  • 普通に FFXI のクライアントを起動。
(09/07 追記) クライアント側は以下の手順じゃないとダメです
  • C:\Windows\system32\drivers\hosts に以下の設定を追記
    127.0.0.1  ffxi00.pol.com
    
  • FFXI のクライアントを起動
  • 同意画面の所まで進める
  • ProjectXI\bin\client\pXi-Clientv.exe でログイン
  • 同意画面で (同意する) のボタンを押す
  • 初めはキャラがいないので、キャラの新規作成から

結果:

問題が発生したため、pXI-Server-0.6.1.exe を終了します。
ご不便をおかけして申し訳ありません。
○rz

めげずに:

エラーダイアログは出てるが、一応プログラムは続行してるので ログコンソールを見ると not found in DB が多発している。 preset 用ファイルではテーブル名が小文字で統一されているが、 大文字の混ざったテーブル名でアクセスしていて、見つからないと怒られてるらしい。
テーブルはファイルにマップされてるので、 Windows で動く MySQL だと問題ないのかな…

それでもめげずに:

試しに接続してみる。
WTF??
Did not find a match?!?!
やっぱりダメか… ○rz

コードを見てみた:

ProjectXI/src/server/src/CNetwork.cpp
if((CGlobal::connectList.size() > 0)) {
        for(i = (CGlobal::connectList.size()-1); i >= 0; i--) {
                //Does the IP match and is the RecvKey free?
                if ((r.ip == CGlobal::connectList.at(i).ip) && (CGlobal::connectList.at(i).s == 0)) {
                        //We found the RecvKey we were looking for!!
                        CConsole::outTime("Found it");
                        break;
                }
        }
}
else {
        //We don't have a list........
        CConsole::outTime("WTF??");
}
//Confirm we are within range and it is valid
if (i < CGlobal::connectList.size()){
        //Store the newly made socket into the connectList
        CGlobal::connectList.at(i).s = r.s;
        CGlobal::connectList.at(i).out = ListenSocket2;
        mysql_thread_init();
        //Run the PolLobbyComm thread
        CreateThread(0,0,PolLobbyComm,&CGlobal::connectList.at(i),0,0);
}
else {
        //How did we not find a match? :(
        CConsole::outTime("Did not find a match?!?!");
}
この connectList に追加する部分は
DWORD WINAPI LobbyServ(LPVOID lpParam)
{
	<略>
while(1) {
        size = sizeof(ip);
        r->out = 0;
        //Listens for our client to connect
        r->s1 = accept(ListenSocket, (struct sockaddr *)&ip, &size);
        if (r->s1 == INVALID_SOCKET) {
        closesocket(ListenSocket);
        CConsole::outErr("accept failed: %d\n", WSAGetLastError());
                WSACleanup();
                return 1;
        }
        //Find the IP address of the client that connected to us
        r->ip = ip.sin_addr.S_un.S_addr;
        r->s = 0;
        //Push the client onto our list
        CGlobal::connectList.push_back(*r);
}
どうも、 54001 の前に 54230 のメッセージを受け取らないといけないのに、 54230 のメッセージが届いてないので、そんなの知らないって言われてそう。 きっと、54230 の thread が落ちてるんだろうなぁ… *1
(ファイアウォールの例外に設定済みなので、届かないって事はないだろうし)
…とりあえず、テーブル名を修正してから考えよう…

テーブル修正後:

SQL preset データがおかしいので修正したら、 エミュ鯖あっさり動いたw
テーブル名の大文字小文字が Preset データとプログラムが要求する文字列とで ずれてたので修正しただけ。
MySQL だけ Linux で動かすという変則的な事したのがまずかったのかも。( ̄― ̄;)
では、オフライン FFXI で遊んできますー 一人ぼっち !||!○rz

動かしてみた:

  • NPC に話しかけても返事なし
  • 魔法のスクロールを使っても習得せず。スクローズ消えないけど
  • 西サルタでバトルが出来た。とりあえず Tiny Mandragora を倒した。
  • 何故か近くの兎(Savanna Rarab)が襲いかかってきたw リンク?ww
  • 戦闘不能になったのでHPに戻るを選択したら、何故かその場で復活したw
  • 試しに兎に近づいたら襲ってきたw アクティブなのかww
楽しすぎるw

GM に変身した所w

コマンド表:

勝手サーバなのでやりたい放題
o @zone - instantly zone yourself to a specified location (e.g. "@zone 0xZZ").
o @additem - puts an item of your choice in your inventory (e.g. "@additem 0xZZZZ").
o @pos - teleport your character to a given position (e.g. "@pos 1 2 3").
o @posr- changes your position relative to your current position (e.g. "@posr 0 2 0").
o @inject - load a packet to be sent to the client (e.g. "@inject packet.dat").
o @debug - print your characters charid and targid to the server
o @gm - toggle GM flag
o @changejob - change your job, the first parameter is the job, the second is the level (e.g. "@changejob 0xA 75")
o @where - echos your current position to the server console.
o @npc - echos the closest npc to you to the server console.
o @zoneR - reloads a zone  (e.g @zoneR 0xf5 (reloads lower jeuno)).
o @hp -	changes your hp, if it sinks to 0, you die. (e.g @hp 0x00 (you die)).
o @mobani - change the animation of the selected mob (e.g @mobani 0x03 (it dies)). 
o @animation - change your character animation (e.g @animation 0x05 (mount a choco)). 
o @cs - play a cutscene in the current zone (e.g. @cs 0x01).
自分以外いないけどねw

その後:

サーバが落ちたので、起動しなおしたら同じ問題(WTF)発生。 さっき動いたのは偶然か。(´Д`;)

*1: (9/9 追記) 54230 は付属の pXi-Clientv.exe でログインする時のパケットみたいです。 同意確認画面が表示されてから、同意するボタンを押すまでの間にログインしないと、 WTF が表示されるのは、54230 のパケットが送られたアドレスを覚えておいて、そこからの 54001 しか許可しないって処理になってる。のかな?

2008年09月05日(金)

ProjectXI を動かしてみた (アイテム追加)

失敗してた理由:

230 :既にその名前は使われています:2008/09/05(金) 02:02:50 ID:9PMMttxt
    WTHが出るのは同意画面に入る前にClientv動かした場合。
    俺はすくなくともそうなった。 
README にもやり方が書いてあるのに。アホでした。
 Launch FFXI and wait at the screen where you get to accept or
decline the terms of agreement (which occurs after the POL version
check, and before the character selection screen).
 Now launch the pXI-client.exe 
とはいえ、少し動かしてるとすぐ落ちるのは変わらず。

着替え実験:

  • 赤魔75にセット
    @changejob 0x5 75
    
  • 上から順に、エクスカリバー、デュエルグローブ+1、デュエルシャポー、デュエルタバード、デュエルタイツ、デュエルタイツのアイテム取得。
    @additem 0x4764
    @additem 0x3A41
    @additem 0x3AE4
    @additem 0x3AF3
    @additem 0x3B11
    @additem 0x3B20
    
  • 結果

2008年09月07日(日)

ProjectXI を動かしてみた (ポジション指定)

@pos コマンドを使ってみた。 引数は (x, -z, y) らしい。

2008年09月08日(月)

[swfed] ming の png の扱い

SWF ファイル内の非可逆圧縮画像のデータは zlib で圧縮されている。 …で、PNG も zlib 圧縮なので、もしかしてうまい事やってないかなと、 ming のコードを覗いてみた。
% mkdir ming
% cd ming
% cvs -d:pserver:anonymous@ming.cvs.sourceforge.net:/cvsroot/ming login 
% cvs -z3 -d:pserver:anonymous@ming.cvs.sourceforge.net:/cvsroot/ming co -P .
ming が PNG を処理するファイルは、ming/util/png2dbl.c,dbl2png.c の2つ。
png2dbl.c の中身
struct pngdata readPNG(FILE *fp)
{
	<略>
  png_read_image(png_ptr, row_pointers);
普通に libpng 経由で zlib 圧縮/伸張してるっぽいです。残念。

学習した事:

やはり、libpng を使って真面目に zlib 圧縮/伸張しよう。
swfed では replacePNGData の API を用意したけど、 これだと差し替える度に、zlib 処理が走るので、 先に PNG を Lossless (か、それに近い形式)に変換しておいて、 replaceLossless で入れ替えた方が実サービスにはいいかも。 と思い始めた。
zlib 圧縮/伸張の処理は重たいので、毎回動くかすのは勿体無い。

追記 (2009年10月7日追記):

「DefineBitsLossless zlib」で検索してこられたかた用のまとめ。

2008年09月09日(火)

php_qr extension

試しに導入。
普通は↓こちらを使いそうですが、 「実行時にはそれなりの負荷がかかる」と明言してるので、 extension の方を試みました。

php_qr-0.1.0.tgz:

コンパイル
phpize
./configure --enable-qr --enable-qr-gd
make
make install
vi /etc/php.d/qr.ini
チェック
%  php -v
PHP Warning:  PHP Startup: Unable to load dynamic library
'/usr/lib/php/modules/qr.so' - /usr/lib/php/modules/qr.so:
undefined symbol: php_input_from_zval in Unknown on line 0
PHP 5.1.6 (cli) (built: Jul 16 2008 19:53:00)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
怒られてる…

php_qr-0.3.1.tgz:

よく見たら 0.3.1 が出てました。 こちらは問題なく使えました。
<?php

$data = 'http://pwiki.awm.jp/~yoya/';
$options = array(
    'format' => QR_FMT_JPEG,
    'magnify' => 4,
    );
header('Content-Type: image/jpeg');
qr_output_symbol(null, $data, $options);

メモ:

  • php_qr-0.3.1 + php 5.1.x, 5.2.x で動作確認した
  • configure で php-config を指定しないと動かない事があるので注意
  • php_qr-0.1.0 が動かなかった原因の php_input_from_zval だけど、php-3.0.1, php-4.0.0, php-5.0.0 で grep しても見つからない。何だろコレ

これで、8 日分だよ〜。

タイトル一覧
カテゴリ分類
Database
JXTA
Java
XML
awm
bookmark
keyword
memo
news
research
Powered by hns-2.19.5, HyperNikkiSystem Project