These pages are written by only Japanese.

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

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


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

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

2010年12月01日(水)

swfed 0.26 release - setActionVariables

setActionVariables が実装出来たのと、一件不具合修正があるので、合わせて 0.26 リリースしました。

setActionVariables:

以下のような PHP で SWF を編集すると、
$swf = new SWFEditor()
$swf->input($swfdata);
$vars = array('input_value' => 'this is pen.');
$swf->setActionVariables($vars);
echo $swf->output();
以下の ActionScript のように変数を受け取る事ができます。
internal_value = input_value

不具合修正:

repacePNGData で透明度付きパレット形式画像を扱った際に、 意図しない場所が透明になる事のある不具合を修正しました。
PNG の tRNS チャンクから透明度情報を抽出する際に、 ひとつ大目に勘違いしていて、透明度付きパレット+1 に対応するパレットの色が透明になる不具合がありました。
ごめんなさい。。

2010年12月05日(日)

swfedがたまに落ちる原因?

たまにといいますか、FreeBSD ではよく落ちるという報告が今年の頭から何度かありまして…
動作確認して次バージョンで出します。

swfed/src/jpeg_segment.c:

jpeg_segment_delete_node(jpeg_segment_t *jpeg_seg, int marker) {
    jpeg_segment_node_t *node;
    int count = 0;
    for (node=jpeg_seg->head ; node ; node=node->next) {
        if (node->marker == marker) {
            node->marker = -1; // remove mark;
            if (node->data_ref) {
                free(node->data_ref); // ☆☆コレ☆☆
                node->data_ref = NULL;
            }
            node->data_len = 0;
            count ++;
        }
    }
    return count;
}
わざわざ free されないように data_ref (他変数の参照だよ) という 分かりやすい変数名にしてたのに。。。シネバイイノニ。 > 自分

2010年12月06日(月)

[phpopengl] glReadPixels調査

phpopengl の glReadPixels が動かないので調査。
php_array_to_long_array した配列を glReadPixels に渡して、 その中に描画バッファを転送させようとして落ちてる。

gdb:

Program received signal SIGSEGV, Segmentation fault.
0x00c3473c in memcpy () from /lib/i686/nosegneg/libc.so.6
(gdb) bt
#0  0x00c3473c in memcpy () from /lib/i686/nosegneg/libc.so.6
#1  0x03b51cb0 in __glEmptyImage () from /usr/lib/libGL.so.1
コピー領域が確保できてない系の落ち方です。

php_convert.h:

#define php_array_to_long_array(z) (long *)php_array_to_c_array(z,TO_C_LONG,sizeof(long),NULL)

php_convert.c:

(関係ない所たくさん削ってみた)
void *php_array_to_c_array(zval *param,int type,int size,int *array_size)
{
    HashTable *param_ht = param->value.ht;
    tmp_size = zend_hash_num_elements(param_ht);
    zend_hash_internal_pointer_reset(param_ht);
    params = (void *)emalloc(size * tmp_size);
    while(zend_hash_get_current_data(param_ht,(void **)&cur) == SUCCESS) {
         convert_to_long(*cur);
         ((long*)params)[i] = Z_LVAL_P(*cur);
         zend_hash_move_forward(param_ht);
         i++;
    }
    return (void *)params;
}
文字通り、PHP の配列を C の配列にマッピングする関数です。
しかも、(上で引用したコードでは省略されてるけど) 入れ子な配列もきちんと、構造体への参照にしてくれる優れもの。

所感。:

そもそも、呼ぶ前に必要な分(width x height)の array を確保しない時点で 落ちるのは、PHP の API として不味いので、そこから見直すべきですが、
width x height 分の array を渡しても落ちたので、多分そもそも動かない。
LONG(4byte)分のメモリ領域を確保してくれてるはずなので、パッと見は大丈夫そうなのですが。
なんだろう。

2010年12月07日(火)

[phpopengl] glReadPixels調査 (2)

glReadPixels に渡すバッファが足りないのは 使い方を間違えていたからでした。
あらかじめ必要な要素数の array を用意しないと seg.fault するのは、前回説明した通りですが、
$pixels = array($width * $height);
で実験していて、これは間違いで、
$pixels = array_fill(0, $width * $height, 0);
です。
一応、これで落ちなくはなったけど。。。

値を受け取れない:

PHP_FUNCTION(glreadpixels)
{
        <略>
    v_pixels = php_array_to_long_array(pixels);
    glReadPixels((int)Z_LVAL_P(x),(int)Z_LVAL_P(y),(int)Z_LVAL_P(width),(int)Z_LVAL_P(height),(int)Z_LVAL_P(format),(int)Z_LVAL_P(type),v_pixels);
}
なので、何も値が返ってきません。

実験:

まず、引数を参照渡しにします。
ZEND_BEGIN_ARG_INFO_EX(force_ref_seventh_arg, 1, 0, 7)
    ZEND_ARG_INFO(0, arg1)
    ZEND_ARG_INFO(0, arg2)
    ZEND_ARG_INFO(0, arg3)
    ZEND_ARG_INFO(0, arg4)
    ZEND_ARG_INFO(0, arg5)
    ZEND_ARG_INFO(0, arg6)
    ZEND_ARG_INFO(1, arg7)
ZEND_END_ARG_INFO()
function_entry opengl_functions[] = {
    <略>
    PHP_FE(glreadpixels,force_ref_seventh_arg)
PHP_FUNCTION(glreadpixels) の 最後に、
        long_array_to_php_array(v_pixels, (int)Z_LVAL_P(width) * Z_LVAL_P(height)* 4 /*U_LONG size*/, pixels);
}
の一行を追加してみたけど、何も変わる様子無いです。
long_array_to_php_array の処理は予想通りだったので、 Zend API の使い方に何か問題があるのかも。

そもそも論:

そもそもこういう配列の使い方すると、メモリがすぐ溢れるので、 PHP の array で値を受け取るのは実用的じゃないよね。
結局のところ、PHP カンファレンスで使った glReadPixels_yoya が現実的な気がします。

2010年12月08日(水)

[phpopengl]glReadPixels GL_RGBAで動きました

こんな感じで動きました。
v_pixels_len = (int)Z_LVAL_P(width) * Z_LVAL_P(height)* sizeof(long);
v_pixels = emalloc(v_pixels_len);
glReadPixels((int)Z_LVAL_P(x),(int)Z_LVAL_P(y),(int)Z_LVAL_P(width),(int)Z_LVAL_P(height),(int)Z_LVAL_P(format),(int)Z_LVAL_P(type),v_pixels);
long_array_to_php_array(v_pixels, v_pixels_len, pixels);

glReadPixelsの使い方 (暫定):

  • 関数の呼び方
    $pixels = array(); // 空配列を渡す
    glReadPixels(0, 0, $width, $height, GL_RGBA, GL_UNSIGNED_BYTE, $pixels);
    
  • 画像ファイル保存 GD で画像を生成する為にピクセルデータを構築するのは、signed long を RGBA として解釈するので、ちょっと面倒だけど。 以下ので出来ました。
    // GD でキャンバスを作る
    $im = imagecreatetruecolor($width, $height);
    $i = 0;
    // pixels 配列を R, G, B, A(無視) の順で解釈してイメージを作成
    for ($y = $height ; $y >= 0; $y--) {
        for ($x = 0; $x < $width ; $x++) {
            $rgb = $pixels[$i];
            if ($rgb < 0) {
                $rgb += 4294967296; // integer => float
            }
            $blue  = $rgb % 0x100 ; $rgb /= 0x100;
            $green = $rgb % 0x100 ; $rgb /= 0x100;
            $red   = $rgb % 0x100 ; $rgb /= 0x100;
            $color = imagecolorallocate($im, $red, $green, $blue);
            imagesetpixel($im, $x, $y, $color); // pixel を埋めていく
            $i ++;
        }
    }
    imagepng($im, "output.png"); // PNG ファイルとして保存!!!
    
    PHP の integer は 0x80000000 以上の正の値を扱えないので、 その場合は float に格上げして、ビット演算をあきらめて mod で処理してます。 (unpack 使えって話ですね。すみません)
  • そもそも:

    PHP で無理やりバイト処理は心臓に悪いので、
    array(array('red'=>..., 'green'=>..., 'blue'=>..., 'alpha'=>...))
    
    の形式で返した方が良いと思いました。
    メモリ使いすぎる問題は、それ以前に(パフォーマンス的に) PHP で こんなループ処理する事自体間違えてるので、extension の C 側の ルーチンで全部処理するのが正しいですね。
    yglImagePNG($filename); みたいにバッファ吸出し&画像出力を C 言語側で閉じて処理する新規 function を作ってみよう。

    これで、5 日分だよ〜。

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