ImageMagick の不具合報告
2件報告しました。同僚に英語を治して貰ったり、タイトルは貰ったものだったりと、ありがたや。ありがたや。
quantize_error を足しこむ計算が間違っている件
同僚が見つけた不具合なので、僕が報告するのは悪いのですが、どうぞと言われたので遠慮なく。><;
- miscalculation of summarized quantize_error
減色処理で複数の色を代表する色に落とし込む際、色ツリーのノード毎に色のばらつき具合を計算しますが、同じ色でも複数使う場合は使われてる分だけ足し込みます。
(http://labs.gree.jp/blog/2012/09/4824/ から引用)
足す場合に色距離を計算するので 6.4.1-3 では色をカウントして、色距離の計算を一度だけにする高速化がされているのですが、sqrt の外でなく中に count の乗算が入っていて前と違う結果になっていました。
- 6.4.1-2
node_info->quantize_error+=sqrt((double) (error.red*error.red+
error.green*error.green+error.blue*error.blue+error.opacity*
error.opacity));
- 6.4.1-3
if (IsColorSimilar(image,p,p+count) == MagickFalse) break; (略) node_info->quantize_error+=sqrt((double) (count*error.red*error.red+ count*error.green*error.green+count*error.blue*error.blue+ count*error.opacity*error.opacity));
正しくはこれ
if (IsColorSimilar(image,p,p+count) == MagickFalse) break; (略) node_info->quantize_error+=count*sqrt((double) (error.red*error.red+ error.green*error.green+error.blue*error.blue+ error.opacity*error.opacity));
ディザ処理で減色ツリーを辿る処理が間違えている件
- quantize tree walking mistake for RiemersmaDither
RiemersmaDither 関数にこんな処理がありまして、
/* Identify the deepest node containing the pixel's color. */ node_info=p->root; for (index=MaxTreeDepth-1; (ssize_t) index > 0; index--) { id=ColorToNodeId(cube_info,&pixel,index); if (node_info->child[id] == (NodeInfo *) NULL) break; node_info=node_info->child[id]; } node_info=node_info->parent; /* Find closest color among siblings and their children. */ p->target=pixel; p->distance=(MagickRealType) (4.0*(QuantumRange+1.0)*((MagickRealType) QuantumRange+1.0)+1.0); ClosestColor(image,p,node_info->parent); p->cache[i]=(ssize_t) p->color_number;
コメントには兄弟ノードとその子供を探索とあります。図ではこんな感じ。(透明の立方体が元のノードで矢印が指すのが辿りつきたいノード)
なのですが、->parent を二回辿っていて実際には叔父ノードを見てしまっています。
実はそっくりな処理が AssignImageColors にもありまして、こっちも前は同じ不具合があったのですが、いつの間にか治っていました。(これを見て間違いだと確信しました)
同じ処理が複数あって片方だけ治すという、ありがちな罠ですね。