こんにちは, I.Tak.です。[osask 7187]に返信です。 Akira Ouchi wrote: >>フルカラー(b_type=4)さえできてしまえば減色ルーチンが使えますが >>……誤差拡散ルーチンの説明はどこにも書いてませんでしたか(^^; >>使います? > > うーん、MLとかにあるのかなぁ?よくわからないのでI.Tak.さんにお任せしま > す。 どこにも書いてないはずですので, この機会に説明してしまおうと思います。 誤差拡散について: 減色すると元の画像と同じ色が使えるとは限らないので, 同じ色が無い場合は暗い色を代わりに使う。生じた誤差は, 隣りのピクセルをその分明るくすることでごまかす。 というものです。 誤差拡散ルーチン仕様: extern void gosakaku16(int delta, int *deltabuffer, int width, const int *source, short *dest); extern void gosakaku6(int delta, int *deltabuffer, int width, const int *source, char *dest); extern void gosakaku4(int delta, int *deltabuffer, int width, const int *source, char *dest); extern void gosakaku3(int delta, int *deltabuffer, int width, const int *source, char *dest); 減色で発生した誤差を右と下へ半分ずつ伝播するタイプの 誤差拡散ルーチン。一行だけ減色する。 delta = 左からの繰り越し誤差。 deltabuffer = 上の行からの繰り越し誤差。 source から width 個の32bpp (RGB888) ピクセルを読み, 16bpp (RGB565), 6bpp (RGB222), 4bpp (IRGB1111), 3bpp (RGB111) に減色して dest に書く。 発生した誤差は deltabuffer に書き込まれるので, 通常は初期化以外に deltabuffer をいじる必要はない。 deltabuffer, source, dest ともにwidth個の要素が必要。 典型的な呼び方: /****************************************/ int i, width = ほげ, height = ほげ; int *deltabuffer = malloc(width * 4), *source = 画像; short *dest = malloc(ほげ); for (i = 0; i < width; i++) deltabuffer[i] = 0; /* 誤差0に初期化 */ for (i = 0; i < height; i++) { /* 上から下までループ */ gosakaku16(0, deltabuffer, width, source, dest); dest += width; /* 次の行へ */ source += width; /* 次の行へ */ } /****************************************/ ここで左からの誤差 delta = 0 としているのは, 画像の左端から右端まで 一気に減色しているため。JPEGのようにブロック単位で処理する場合は 左のブロックから誤差を持って来る必要がある。 こんな感じです。宣言がjpeg.cに書いてあるのと微妙に違いますが, アセンブリ言語はそのへんいい加減なので気にしないでください;-) I.Tak.<t40370@mail.ecc.u-tokyo.ac.jp>