Browse Source

* Error diffusion methods now support either raster or serpentine scan.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2656 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 years ago
parent
commit
87f8e922ab
5 changed files with 34 additions and 15 deletions
  1. +12
    -6
      examples/dither.c
  2. +1
    -1
      examples/edd.c
  3. +5
    -3
      pipi/dither/floydsteinberg.c
  4. +5
    -3
      pipi/dither/ostromoukhov.c
  5. +11
    -2
      pipi/pipi.h

+ 12
- 6
examples/dither.c View File

@@ -17,9 +17,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "%s: too few arguments\n", argv[0]);
fprintf(stderr, "Usage: %s <src> <method> <dest>\n", argv[0]);
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;
}

@@ -30,13 +32,17 @@ int main(int argc, char *argv[])

switch(atoi(argv[2]))
{
case 3:
case 5:
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:
newimg = pipi_ostromoukhov(img); break;
newimg = pipi_floydsteinberg(img, PIPI_SCAN_SERPENTINE); break;
case 1:
default:
newimg = pipi_floydsteinberg(img); break;
newimg = pipi_floydsteinberg(img, PIPI_SCAN_RASTER); break;
}

pipi_free(img);


+ 1
- 1
examples/edd.c View File

@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
img = pipi_load(argv[1]);
pipi_getpixels(img, PIPI_PIXELS_Y_F);
gauss = pipi_gaussian_blur(img, sigma);
dither = pipi_floydsteinberg(img);
dither = pipi_floydsteinberg(img, PIPI_SCAN_RASTER);
pipi_free(img);

/* Compute the standard error */


+ 5
- 3
pipi/dither/floydsteinberg.c View File

@@ -22,7 +22,7 @@
#include "pipi.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_pixels_t *srcp, *dstp;
@@ -41,11 +41,13 @@ pipi_image_t *pipi_floydsteinberg(pipi_image_t *src)

for(y = 0; y < h; y++)
{
int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE);

for(x = 0; x < w; x++)
{
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];
q = p < 0.5 ? 0. : 1.;


+ 5
- 3
pipi/dither/ostromoukhov.c View File

@@ -66,7 +66,7 @@ static int const table[][3] =
{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_pixels_t *srcp, *dstp;
@@ -85,13 +85,15 @@ pipi_image_t *pipi_ostromoukhov(pipi_image_t *src)

for(y = 0; y < h; y++)
{
int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE);

for(x = 0; x < w; x++)
{
float p, q, e;
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];
q = p < 0.5 ? 0. : 1.;


+ 11
- 2
pipi/pipi.h View File

@@ -24,6 +24,15 @@ extern "C"
{
#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
* 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. */
@@ -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 *,
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 void pipi_dither_24to16(pipi_image_t *);



Loading…
Cancel
Save