git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2670 92316355-f0b4-4df1-b90c-862c8a59935fremotes/tiles
@@ -35,14 +35,14 @@ | |||||
/* FIXME: though the algorithm is supposed to stop, we do not have a real, | /* FIXME: though the algorithm is supposed to stop, we do not have a real, | ||||
* guaranteed stop condition here. */ | * guaranteed stop condition here. */ | ||||
pipi_image_t *pipi_dither_dbs(pipi_image_t *src) | |||||
pipi_image_t *pipi_dither_dbs(pipi_image_t *img) | |||||
{ | { | ||||
double kernel[NN * NN]; | double kernel[NN * NN]; | ||||
double t = 0.; | double t = 0.; | ||||
pipi_image_t *dst, *tmp1, *tmp2; | |||||
pipi_pixels_t *srcp, *dstp, *tmp1p, *tmp2p; | |||||
pipi_image_t *src, *dst, *tmp1, *tmp2; | |||||
pipi_pixels_t *dstp, *tmp1p, *tmp2p; | |||||
int *changelist; | int *changelist; | ||||
float *srcdata, *dstdata, *tmp1data, *tmp2data; | |||||
float *dstdata, *tmp1data, *tmp2data; | |||||
int i, j, x, y, w, h, cw, ch; | int i, j, x, y, w, h, cw, ch; | ||||
/* Build our human visual system kernel. */ | /* Build our human visual system kernel. */ | ||||
@@ -61,31 +61,26 @@ pipi_image_t *pipi_dither_dbs(pipi_image_t *src) | |||||
for(i = 0; i < NN; i++) | for(i = 0; i < NN; i++) | ||||
kernel[j * NN + i] /= t; | kernel[j * NN + i] /= t; | ||||
w = src->w; | |||||
h = src->h; | |||||
w = img->w; | |||||
h = img->h; | |||||
cw = (w + CELL - 1) / CELL; | cw = (w + CELL - 1) / CELL; | ||||
ch = (h + CELL - 1) / CELL; | ch = (h + CELL - 1) / CELL; | ||||
changelist = malloc(cw * ch * sizeof(int)); | changelist = malloc(cw * ch * sizeof(int)); | ||||
memset(changelist, 0, cw * ch * sizeof(int)); | memset(changelist, 0, cw * ch * sizeof(int)); | ||||
srcp = pipi_getpixels(src, PIPI_PIXELS_Y_F); | |||||
srcdata = (float *)srcp->pixels; | |||||
src = pipi_copy(img); | |||||
pipi_getpixels(src, PIPI_PIXELS_Y_F); | |||||
tmp1 = pipi_convolution(src, NN, NN, kernel); | tmp1 = pipi_convolution(src, NN, NN, kernel); | ||||
tmp1p = pipi_getpixels(tmp1, PIPI_PIXELS_Y_F); | tmp1p = pipi_getpixels(tmp1, PIPI_PIXELS_Y_F); | ||||
tmp1data = (float *)tmp1p->pixels; | tmp1data = (float *)tmp1p->pixels; | ||||
/* The initial dither is an empty image. So is its blurred version, | |||||
* but I leave the pipi_convolution() call here in case we choose | |||||
* to change the way to create the initial dither. */ | |||||
dst = pipi_new(w, h); | |||||
dst = pipi_dither_floydsteinberg(src, PIPI_SCAN_SERPENTINE); | |||||
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | ||||
dstdata = (float *)dstp->pixels; | dstdata = (float *)dstp->pixels; | ||||
for(y = 0; y < h; y++) | |||||
for(x = 0; x < w; x++) | |||||
dstdata[y * w + x] = srcdata[y * w + x] > 0.5 ? 1.0 : 0.0; | |||||
pipi_free(src); | |||||
tmp2 = pipi_convolution(dst, NN, NN, kernel); | tmp2 = pipi_convolution(dst, NN, NN, kernel); | ||||
tmp2p = pipi_getpixels(tmp2, PIPI_PIXELS_Y_F); | tmp2p = pipi_getpixels(tmp2, PIPI_PIXELS_Y_F); | ||||
@@ -22,20 +22,17 @@ | |||||
#include "pipi.h" | #include "pipi.h" | ||||
#include "pipi_internals.h" | #include "pipi_internals.h" | ||||
pipi_image_t *pipi_dither_floydsteinberg(pipi_image_t *src, pipi_scan_t scan) | |||||
pipi_image_t *pipi_dither_floydsteinberg(pipi_image_t *img, pipi_scan_t scan) | |||||
{ | { | ||||
pipi_image_t *dst; | pipi_image_t *dst; | ||||
pipi_pixels_t *srcp, *dstp; | |||||
float *srcdata, *dstdata; | |||||
pipi_pixels_t *dstp; | |||||
float *dstdata; | |||||
int x, y, w, h; | int x, y, w, h; | ||||
w = src->w; | |||||
h = src->h; | |||||
w = img->w; | |||||
h = img->h; | |||||
srcp = pipi_getpixels(src, PIPI_PIXELS_Y_F); | |||||
srcdata = (float *)srcp->pixels; | |||||
dst = pipi_new(w, h); | |||||
dst = pipi_copy(img); | |||||
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | ||||
dstdata = (float *)dstp->pixels; | dstdata = (float *)dstp->pixels; | ||||
@@ -49,7 +46,7 @@ pipi_image_t *pipi_dither_floydsteinberg(pipi_image_t *src, pipi_scan_t scan) | |||||
int x2 = reverse ? w - 1 - x : x; | int x2 = reverse ? w - 1 - x : x; | ||||
int s = reverse ? -1 : 1; | int s = reverse ? -1 : 1; | ||||
p = srcdata[y * w + x2]; | |||||
p = dstdata[y * w + x2]; | |||||
q = p < 0.5 ? 0. : 1.; | q = p < 0.5 ? 0. : 1.; | ||||
dstdata[y * w + x2] = q; | dstdata[y * w + x2] = q; | ||||
@@ -57,14 +54,14 @@ pipi_image_t *pipi_dither_floydsteinberg(pipi_image_t *src, pipi_scan_t scan) | |||||
* error diffusion kernel for serpentine scan. */ | * error diffusion kernel for serpentine scan. */ | ||||
e = p - q; | e = p - q; | ||||
if(x < w - 1) | if(x < w - 1) | ||||
srcdata[y * w + x2 + s] += e * .4375; | |||||
dstdata[y * w + x2 + s] += e * .4375; | |||||
if(y < h - 1) | if(y < h - 1) | ||||
{ | { | ||||
if(x > 0) | if(x > 0) | ||||
srcdata[(y + 1) * w + x2 - s] += e * .1875; | |||||
srcdata[(y + 1) * w + x2] += e * .3125; | |||||
dstdata[(y + 1) * w + x2 - s] += e * .1875; | |||||
dstdata[(y + 1) * w + x2] += e * .3125; | |||||
if(x < w - 1) | if(x < w - 1) | ||||
srcdata[(y + 1) * w + x2 + s] += e * .0625; | |||||
dstdata[(y + 1) * w + x2 + s] += e * .0625; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -34,20 +34,17 @@ static const int kernel8x8[8 * 8] = | |||||
63, 31, 55, 23, 61, 29, 53, 21, | 63, 31, 55, 23, 61, 29, 53, 21, | ||||
}; | }; | ||||
pipi_image_t *pipi_dither_ordered(pipi_image_t *src) | |||||
pipi_image_t *pipi_dither_ordered(pipi_image_t *img) | |||||
{ | { | ||||
pipi_image_t *dst; | pipi_image_t *dst; | ||||
pipi_pixels_t *srcp, *dstp; | |||||
float *srcdata, *dstdata; | |||||
pipi_pixels_t *dstp; | |||||
float *dstdata; | |||||
int x, y, w, h; | int x, y, w, h; | ||||
w = src->w; | |||||
h = src->h; | |||||
w = img->w; | |||||
h = img->h; | |||||
srcp = pipi_getpixels(src, PIPI_PIXELS_Y_F); | |||||
srcdata = (float *)srcp->pixels; | |||||
dst = pipi_new(w, h); | |||||
dst = pipi_copy(img); | |||||
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | ||||
dstdata = (float *)dstp->pixels; | dstdata = (float *)dstp->pixels; | ||||
@@ -57,7 +54,7 @@ pipi_image_t *pipi_dither_ordered(pipi_image_t *src) | |||||
{ | { | ||||
float p, q; | float p, q; | ||||
p = srcdata[y * w + x]; | |||||
p = dstdata[y * w + x]; | |||||
q = p > (1. + kernel8x8[(y % 8) * 8 + (x % 8)]) / 65. ? 1. : 0.; | q = p > (1. + kernel8x8[(y % 8) * 8 + (x % 8)]) / 65. ? 1. : 0.; | ||||
dstdata[y * w + x] = q; | dstdata[y * w + x] = q; | ||||
} | } | ||||
@@ -66,20 +66,17 @@ static int const table[][3] = | |||||
{385, 112, 103}, {65, 18, 17}, {395, 104, 101}, {4, 1, 1} | {385, 112, 103}, {65, 18, 17}, {395, 104, 101}, {4, 1, 1} | ||||
}; | }; | ||||
pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *src, pipi_scan_t scan) | |||||
pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *img, pipi_scan_t scan) | |||||
{ | { | ||||
pipi_image_t *dst; | pipi_image_t *dst; | ||||
pipi_pixels_t *srcp, *dstp; | |||||
float *srcdata, *dstdata; | |||||
pipi_pixels_t *dstp; | |||||
float *dstdata; | |||||
int x, y, w, h; | int x, y, w, h; | ||||
w = src->w; | |||||
h = src->h; | |||||
w = img->w; | |||||
h = img->h; | |||||
srcp = pipi_getpixels(src, PIPI_PIXELS_Y_F); | |||||
srcdata = (float *)srcp->pixels; | |||||
dst = pipi_new(w, h); | |||||
dst = pipi_copy(img); | |||||
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F); | ||||
dstdata = (float *)dstp->pixels; | dstdata = (float *)dstp->pixels; | ||||
@@ -95,7 +92,7 @@ pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *src, pipi_scan_t scan) | |||||
x2 = reverse ? w - 1 - x : x; | x2 = reverse ? w - 1 - x : x; | ||||
s = reverse ? -1 : 1; | s = reverse ? -1 : 1; | ||||
p = srcdata[y * w + x2]; | |||||
p = dstdata[y * w + x2]; | |||||
q = p < 0.5 ? 0. : 1.; | q = p < 0.5 ? 0. : 1.; | ||||
dstdata[y * w + x2] = q; | dstdata[y * w + x2] = q; | ||||
@@ -106,12 +103,12 @@ pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *src, pipi_scan_t scan) | |||||
e /= table[i][0] + table[i][1] + table[i][2]; | e /= table[i][0] + table[i][1] + table[i][2]; | ||||
if(x < w - 1) | if(x < w - 1) | ||||
srcdata[y * w + x2 + s] += e * table[i][0]; | |||||
dstdata[y * w + x2 + s] += e * table[i][0]; | |||||
if(y < h - 1) | if(y < h - 1) | ||||
{ | { | ||||
if(x > 0) | if(x > 0) | ||||
srcdata[(y + 1) * w + x2 - s] += e * table[i][1]; | |||||
srcdata[(y + 1) * w + x2] += e * table[i][2]; | |||||
dstdata[(y + 1) * w + x2 - s] += e * table[i][1]; | |||||
dstdata[(y + 1) * w + x2] += e * table[i][2]; | |||||
} | } | ||||
} | } | ||||
} | } | ||||