git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2656 92316355-f0b4-4df1-b90c-862c8a59935fremotes/tiles
@@ -17,9 +17,11 @@ int main(int argc, char *argv[]) | |||||
fprintf(stderr, "%s: too few arguments\n", argv[0]); | fprintf(stderr, "%s: too few arguments\n", argv[0]); | ||||
fprintf(stderr, "Usage: %s <src> <method> <dest>\n", argv[0]); | fprintf(stderr, "Usage: %s <src> <method> <dest>\n", argv[0]); | ||||
fprintf(stderr, "Where <method> is one of:\n"); | fprintf(stderr, "Where <method> is one of:\n"); | ||||
fprintf(stderr, " 1 Floyd-Steinberg (serpentine)\n"); | |||||
fprintf(stderr, " 2 Ostromoukhov (serpentine)\n"); | |||||
fprintf(stderr, " 3 Direct binary search\n"); | |||||
fprintf(stderr, " 1 Floyd-Steinberg (raster)\n"); | |||||
fprintf(stderr, " 2 Floyd-Steinberg (serpentine)\n"); | |||||
fprintf(stderr, " 3 Ostromoukhov (raster)\n"); | |||||
fprintf(stderr, " 4 Ostromoukhov (serpentine)\n"); | |||||
fprintf(stderr, " 5 Direct binary search\n"); | |||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
@@ -30,13 +32,17 @@ int main(int argc, char *argv[]) | |||||
switch(atoi(argv[2])) | switch(atoi(argv[2])) | ||||
{ | { | ||||
case 3: | |||||
case 5: | |||||
newimg = pipi_dbs(img); break; | newimg = pipi_dbs(img); break; | ||||
case 4: | |||||
newimg = pipi_ostromoukhov(img, PIPI_SCAN_SERPENTINE); break; | |||||
case 3: | |||||
newimg = pipi_ostromoukhov(img, PIPI_SCAN_RASTER); break; | |||||
case 2: | case 2: | ||||
newimg = pipi_ostromoukhov(img); break; | |||||
newimg = pipi_floydsteinberg(img, PIPI_SCAN_SERPENTINE); break; | |||||
case 1: | case 1: | ||||
default: | default: | ||||
newimg = pipi_floydsteinberg(img); break; | |||||
newimg = pipi_floydsteinberg(img, PIPI_SCAN_RASTER); break; | |||||
} | } | ||||
pipi_free(img); | pipi_free(img); | ||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) | |||||
img = pipi_load(argv[1]); | img = pipi_load(argv[1]); | ||||
pipi_getpixels(img, PIPI_PIXELS_Y_F); | pipi_getpixels(img, PIPI_PIXELS_Y_F); | ||||
gauss = pipi_gaussian_blur(img, sigma); | gauss = pipi_gaussian_blur(img, sigma); | ||||
dither = pipi_floydsteinberg(img); | |||||
dither = pipi_floydsteinberg(img, PIPI_SCAN_RASTER); | |||||
pipi_free(img); | pipi_free(img); | ||||
/* Compute the standard error */ | /* Compute the standard error */ | ||||
@@ -22,7 +22,7 @@ | |||||
#include "pipi.h" | #include "pipi.h" | ||||
#include "pipi_internals.h" | #include "pipi_internals.h" | ||||
pipi_image_t *pipi_floydsteinberg(pipi_image_t *src) | |||||
pipi_image_t *pipi_floydsteinberg(pipi_image_t *src, pipi_scan_t scan) | |||||
{ | { | ||||
pipi_image_t *dst; | pipi_image_t *dst; | ||||
pipi_pixels_t *srcp, *dstp; | pipi_pixels_t *srcp, *dstp; | ||||
@@ -41,11 +41,13 @@ pipi_image_t *pipi_floydsteinberg(pipi_image_t *src) | |||||
for(y = 0; y < h; y++) | for(y = 0; y < h; y++) | ||||
{ | { | ||||
int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE); | |||||
for(x = 0; x < w; x++) | for(x = 0; x < w; x++) | ||||
{ | { | ||||
float p, q, e; | float p, q, e; | ||||
int x2 = (y & 1) ? x : w - 1 - x; | |||||
int s = (y & 1) ? 1 : -1; | |||||
int x2 = reverse ? w - 1 - x : x; | |||||
int s = reverse ? -1 : 1; | |||||
p = srcdata[y * w + x2]; | p = srcdata[y * w + x2]; | ||||
q = p < 0.5 ? 0. : 1.; | q = p < 0.5 ? 0. : 1.; | ||||
@@ -66,7 +66,7 @@ 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_ostromoukhov(pipi_image_t *src) | |||||
pipi_image_t *pipi_ostromoukhov(pipi_image_t *src, pipi_scan_t scan) | |||||
{ | { | ||||
pipi_image_t *dst; | pipi_image_t *dst; | ||||
pipi_pixels_t *srcp, *dstp; | pipi_pixels_t *srcp, *dstp; | ||||
@@ -85,13 +85,15 @@ pipi_image_t *pipi_ostromoukhov(pipi_image_t *src) | |||||
for(y = 0; y < h; y++) | for(y = 0; y < h; y++) | ||||
{ | { | ||||
int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE); | |||||
for(x = 0; x < w; x++) | for(x = 0; x < w; x++) | ||||
{ | { | ||||
float p, q, e; | float p, q, e; | ||||
int x2, s, i; | int x2, s, i; | ||||
x2 = (y & 1) ? x : w - 1 - x; | |||||
s = (y & 1) ? 1 : -1; | |||||
x2 = reverse ? w - 1 - x : x; | |||||
s = reverse ? -1 : 1; | |||||
p = srcdata[y * w + x2]; | p = srcdata[y * w + x2]; | ||||
q = p < 0.5 ? 0. : 1.; | q = p < 0.5 ? 0. : 1.; | ||||
@@ -24,6 +24,15 @@ extern "C" | |||||
{ | { | ||||
#endif | #endif | ||||
/* pipi_scan_t: this enum is a list of all possible scanning methods when | |||||
* parsing an image’s pixels. Not all functions support all scanning paths. */ | |||||
typedef enum | |||||
{ | |||||
PIPI_SCAN_RASTER = 0, | |||||
PIPI_SCAN_SERPENTINE = 1 | |||||
} | |||||
pipi_scan_t; | |||||
/* pipi_format_t: this enum is a list of all possible pixel formats for | /* pipi_format_t: this enum is a list of all possible pixel formats for | ||||
* our internal images. RGBA32 is the most usual format when an image has | * our internal images. RGBA32 is the most usual format when an image has | ||||
* just been loaded, but RGBA_F is a lot better for complex operations. */ | * just been loaded, but RGBA_F is a lot better for complex operations. */ | ||||
@@ -68,8 +77,8 @@ extern pipi_image_t *pipi_gaussian_blur(pipi_image_t *, float); | |||||
extern pipi_image_t *pipi_gaussian_blur_ext(pipi_image_t *, | extern pipi_image_t *pipi_gaussian_blur_ext(pipi_image_t *, | ||||
float, float, float, float); | float, float, float, float); | ||||
extern pipi_image_t *pipi_floydsteinberg(pipi_image_t *); | |||||
extern pipi_image_t *pipi_ostromoukhov(pipi_image_t *); | |||||
extern pipi_image_t *pipi_floydsteinberg(pipi_image_t *, pipi_scan_t); | |||||
extern pipi_image_t *pipi_ostromoukhov(pipi_image_t *, pipi_scan_t); | |||||
extern pipi_image_t *pipi_dbs(pipi_image_t *); | extern pipi_image_t *pipi_dbs(pipi_image_t *); | ||||
extern void pipi_dither_24to16(pipi_image_t *); | extern void pipi_dither_24to16(pipi_image_t *); | ||||