上へ

開発メモ

2004/05/06 ジェネリック

画像処理を書いていると

こんなのや
  Count := N shr 3 + 1;
  RestMask := not (SetMask shl ((N and $07) * 8));

  asm
    ...初期化...
    MOV         ECX, Count
    JMP         @Enter
  @@:
    MOVQ        [EDI], MM0
    ADD         ESI, 8
    ADD         EDI, 8
    ADD         EDX, 8
  @Enter:
    MOVQ        MM0, [ESI]      // MM0 S1
    ...処理の実体...
    PMAXUB,PMINUB,PADDUSB,PSUBUSB,PAND,POR,PXOR,等

    DEC         ECX
    JNZ         @@

    // 8byte 境界外処理
    MOVQ      MM2, RestMask
    MOVQ      MM1, [EDI]
    PAND      MM0, MM2
    PANDN     MM2, MM1
    POR       MM0, MM2
    MOVQ      [EDI], MM0
    ...終了処理...
  end;
8byte 境界に直して、PMAXUB,PMINUB,・・・を適用。
現状の実装はテーブルジャンプ、ジェネリックで生成しまくるよりはテーブルジャンプは妥当かもしれない。ただし 同じ MMX でも PMAX,PMIN系が使える場合、使えない場合の2系列がある。さらに Byte だけでなく符号付/無し Word,DWORD,さらにその組み合わせ・・・となるとやっぱりジェネリックは欲しくなる。
こんなのや
  //IX := Max(0, Min(IX, SSX - 1)
  if (IX < 0) then
    IX := 0
  else if (IX > SSX - 1) then
    IX := SSX - 1;
IXを 0 から SSX - 1 の範囲にクリッピング、
関数呼び出しのオーバーヘッドが無視できないので、可読性を犠牲にしてベタ展開。

がよく出てくる。C++ のマクロ、テンプレート、インラインのようなものが使えれば問題は解決するけど Delphi には無い(*)。だからと言って C++ で書くとマクロその他が使えるメリットを帳消しにする生産性の低下(作者の場合)が目に見えている。Delphi 用のプリプロセッサがあれば良いのにと思って探したが無いらしい。.net がどうだこうだの時に、こんなアホなこと考えてるのは作者だけか?

(*){$INCLUDE }という小技もあるにはあるけど。マクロその他は下手に使われた場合のダメージが大きいので、スキルがまちまちなプログラマによる通常のアプリケーション開発の場面では、簡単に使えないほうがありがたかったりする。D言語なんかは意図的にプリプロセッサ付けてないし。

2004/05/07 覚書

A + (A + 1) + (A + 2) + ... + (A + N - 1) = (N * (2 * A + N - 1)) div 2
A^2 + (A + 1)^2 + (A + 2)^2 + ... + (A + N - 1)^2 = N * A * (A + N - 1) + N * (N - 1) * (2 * N - 1) div 6

2004/05/07 lanczos

BiCubic 補間よりきれいな画像補間方法として lanczos というのがあるらしい、グラフを書かせてみるとこんな感じ。

sinc = sin(PI * X) / (PI * X)
bicubic(A) = (A + 2) * X^3 - (A + 3) * X^2 + 1(|X|<=1),A * X^3 - 5 * A * X^2 + 8 * A * X - 4 * A(|X|<=2)
lanczos2 = sinc * sin(PI*X / 2) / (PI * X / 2)
lanczos3 = sinc * sin(PI*X / 3) / (PI * X / 3)

lanczos3を解像感・リンギング・エイリアスのバランスが取れた曲線とすると、bicubic は解像感が強調されすぎてリンギングが出やすいように見える。精度の高い画像回転を求められる場面もあるから lanczos3 も作っておきたいところだけど、lanczos3 では1画素を決める時の参照画素数は36(=6 *6)画素で bicubic の16(=4*4)画素の2倍以上。sin計算もあるので bicubic の延長で実装すると実用的なスピードはどう考えても出ない。lanczos 曲線をテーブル化して、浮動少数を固定少数にして・・・楽しそうだけど当分やれる暇は無いかな。つまらん。