Blog

Tech Note「OpenMP」加筆

Tech NoteOpenMP の加筆を再開しました。
情報量がもう少し増えてきたら、ページを分割して見やすく整理しようと思ってます。

PThreadsと比べるとOpenMPは使うだけなら楽です。
ただ、マルチスレッドプログラミング一般の知識を持たずに使ってもあまり効果は出ないでしょう。
それどころか危険なコードに化けてしまう可能性の方が高いです。。
基礎は大事ですね。

 

HTML5でSymmetric Nearest Neighbor

久しぶりの投稿;

Demo: HTML5 Image Processing (Symmetric Nearest Neighbor)
(Firefox3.5とSafari4で動作確認しています)

HTML5でConvolutionFilterに続いて、簡単な画像処理を試してみます。
以前、ActionScriptで書いたSymmetric Nearest NeighborをJavaScriptで。
半径を大きくするとそれなりに絵画っぽくなってくれますが、やはり重いです;

・クライアント

var context = document.getElementById('Canvas').getContext('2d');
var bmp = new Bitmap('sample.jpg', context);
var radius = 3;
bmp.applyFilter(new SNNFilter(radius));

bitmap.js
(関係ある箇所だけ抜粋)

var Bitmap =  function(source, context) {
  this.initialize.apply(this, arguments);
};

var SNNFilter = function(radius) {
  this.initialize.apply(this, arguments);
};

Bitmap.prototype = {
  initialize : function(source, context) {
    this.bitmapData = new Image();
    this.bitmapData.src = source;
    this.width = this.bitmapData.width;
    this.height = this.bitmapData.height;
    this.context = context;
    this.bitmapData.addEventListener('error', function() { alert("can't load image"); }, false);
  },
  applyFilter : function(filter) {
    try {
      this.context.drawImage(this.bitmapData, 0, 0);
      var src = this.context.getImageData(0, 0, this.width, this.height);
      var dst = this.context.createImageData(this.width, this.height);
      filter.apply(src, dst);
      this.context.putImageData(dst, 0, 0);
    }catch(e) {
      alert(e);
    }
  }
};

SNNFilter.prototype = {
  initialize : function(radius) {
    this.radius = radius;
  },
  apply : function(src, dst) {
    var w = src.width, h = src.height;
    var srcData = src.data;
    var dstData = dst.data;
    var sunR, sumG, sumB;
    var rc, gc, bc, r1, g1, b1, r2, g2, b2;
    var cnt = 0;
    var xyPos, uvPos;

    for(var y=0;y<h;++y) {
      for(var x=0;x<w;++x) {
        xyPos = (w*y + x) << 2;
        sumR = 0, sumG = 0, sumB = 0;
        cnt = 0;
        rc = srcData[xyPos];
        gc = srcData[xyPos + 1];
        bc = srcData[xyPos + 2];
        for(var v=-this.radius;v<=this.radius;++v) {
          for(var u=-this.radius;u<=this.radius;++u,++cnt) {
            uvPos = (w*v + u) << 2;
            try {
              r1 = srcData[xyPos + uvPos];
              g1 = srcData[xyPos + uvPos + 1];
              b1 = srcData[xyPos + uvPos + 2];
              r2 = srcData[xyPos - uvPos];
              g2 = srcData[xyPos - uvPos + 1];
              b2 = srcData[xyPos - uvPos + 2];
            }catch(e) {
              break;
            }
            if(this.delta.apply(this, [rc, gc, bc, r1, g1, b1]) < this.delta.apply(this, [rc, gc, bc, r2, g2, b2])) {
              sumR += r1;
              sumG += g1;
              sumB += b2;
            }else {
              sumR += r2;
              sumG += g2;
              sumB += b2;
            }
          }
        }
        dstData[xyPos] = sumR/cnt;
        dstData[xyPos + 1] = sumG/cnt;
        dstData[xyPos + 2] = sumB/cnt;
        dstData[xyPos + 3] = 255;
      }
    }
  },
  delta : function(rc, gc, bc, r1, g1, b1) {
    return Math.sqrt((rc - r1)*(rc - r1) + (gc - g1)*(gc - g1) + (bc - b1)*(bc - b1));
  }
};

最近、HTML5とFlashの話題が盛んですね。
これまでは 主に canvas を利用したものしか試してないんですが、
業務で動画配信に携わっているので video に関することも調査中です。
技術の外側でH.264/Theoraを巡る政治的な争いを見守りつつ、
来年度からのスタートに出遅れないように今の内にしっかり勉強しておきたいです。

・関連記事
Symmetric Nearest Neighbor « Rest Term
HTML5の勉強 « Rest Term

 

メイリオ

実はメイリオまだ進化中! 誕生秘話を河野氏に聞いた - @IT

たくさんはてブされてる記事なので読んだ人も多いかもしれませんがこれは熟読すべき!
河野氏は熱い人だなぁ。一文字へのこだわりがすごい。
Wikipediaの項目もなんだか熱い気がする。。(メイリオ – Wikipedia)

社内プレゼンで使うフォントはメイリオにしよう。
あと、Windows 7には Meiryo UI が入っているので要確認。

・関連記事
XPでも「メイリオ」が正式利用可能に

 

libevent

libeventを使ったhello, world的な小さなプログラム。
(libeventはmemcachedやThriftなどでも利用されているイベント通知API)

・ファイルが更新されたら内容を表示する

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <event.h>

#define BUF 256

void callback(int fd, short event, void* arg);

int main(int argc, char** argv) {
	int fd;
	struct event ev;
	if((fd = open(argv[1], O_RDONLY)) == -1) {
		perror("open");
		return -1;
	}
	event_init();
	event_set(&ev, fd, EV_READ | EV_PERSIST, callback, &ev);
	event_add(&ev, NULL);
	event_dispatch();
	return 0;
}

void callback(int fd, short event, void* arg) {
	char buf[BUF];
	int len;
	//  event_add((struct event*)arg, NULL);
	if((len = read(fd, buf, sizeof(buf) - 1)) == -1) {
		perror("read");
		return;
	}
	buf[len] = '\0';
	printf("%s", buf);
}

event_set 関数で EV_PERSIST を指定すると、イベント通知を継続して受け取ります。
これを指定しない場合は、コールバック関数内で再度 event_add 関数を呼び出す必要があります。
また、登録したイベントを削除したい場合は event_del 関数を利用します。

・参考
libevent + 使い方 | NINXIT-BLOG

 

welcome 2010

新年あけましておめでとうございます。
今年も思いっきり走り抜けたいと思います!

Webエンジニアとしても学びたいことはたくさん。
今年の目標としては、

KVS(Key-Value Store)について深く学ぶ
モダンPerlなコードを書く
システム運用(トラフィックの監視、負荷分散など)を学ぶ

一つめはKey-Value Store。
僕が一番最初に担当した案件からKVSを利用したメディア配信系のシステムだったりして、
全社的にNoSQLへの流れが強くなっています。
業界全体としても大規模なWebアプリケーションを開発するには必要不可欠な技術なので、
これは最優先で取り組むべき課題としたいです。

二つめはPerl。
弊社のサービスフロントエンドの多くはPHPで構築されるようになりましたが、
新規開発案件でPerlが採用されるケースも多いです(Rubyはまだ残念ながら、、)。
僕は会社に入るまでPerlをまともに触ったことがなかったので、一からの勉強に苦労しました。
Perlのモジュールを速く丁寧に書けるようになりたいと思い二つめの目標に。

三つ目はシステム運用。
インフラ寄りの部署に所属しているので、システム運用の業務も行います。
ある程度人のいる会社では開発と運用の分離をしていて、開発担当が運用業務を行うことはあまりないかもしれません。
ただ、こういった分野は大規模な設備で実務を通して学ばないとあまり身に付かないので、
この部署にいる内に一生懸命勉強しておきたいと思います。

あと、もちろんFlashも。
ASはともかくライブラリ/フレームワークには疎くなってしまったので、
そういった制作寄りの情報も追いかけつつ、Webサイト作りなどもやっていきたいと思います。

2010年もよろしくおねがいします。