Ver código fonte

* Get rid of the specific error diffusion functions, since our stock kernels

work perfectly well.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2759 92316355-f0b4-4df1-b90c-862c8a59935f
remotes/tiles
sam 16 anos atrás
pai
commit
44c9b8e15d
10 arquivos alterados com 63 adições e 255 exclusões
  1. +4
    -2
      examples/edd.c
  2. +0
    -3
      pipi/Makefile.am
  3. +1
    -0
      pipi/codec.c
  4. +9
    -13
      pipi/context.c
  5. +0
    -75
      pipi/dither/atkinson.c
  6. +4
    -1
      pipi/dither/ediff.c
  7. +0
    -71
      pipi/dither/floydsteinberg.c
  8. +0
    -87
      pipi/dither/jajuni.c
  9. +0
    -3
      pipi/pipi.h
  10. +45
    -0
      pipi/stock.c

+ 4
- 2
examples/edd.c Ver arquivo

@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
double sigma = 1.2, precision = 0.001, step = 2.;
double best = 1., fx = -1., fy = -1., bfx = 0., bfy = 0.;
double e, e0, e1;
pipi_image_t *img, *gauss, *dither, *tmp;
pipi_image_t *img, *kernel, *gauss, *dither, *tmp;
int dx, dy;

if(argc < 2)
@@ -52,7 +52,9 @@ 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_dither_floydsteinberg(img, PIPI_SCAN_RASTER);
kernel = pipi_load("ediff:fs");
dither = pipi_dither_ediff(img, kernel, PIPI_SCAN_RASTER);
pipi_free(kernel);
pipi_free(img);

/* Compute the standard error */


+ 0
- 3
pipi/Makefile.am Ver arquivo

@@ -65,9 +65,6 @@ quantize_sources = \

dither_sources = \
dither/ediff.c \
dither/floydsteinberg.c \
dither/jajuni.c \
dither/atkinson.c \
dither/ordered.c \
dither/ostromoukhov.c \
dither/dbs.c \


+ 1
- 0
pipi/codec.c Ver arquivo

@@ -29,6 +29,7 @@
pipi_image_t *pipi_load(char const *name)
{
if(!strncmp(name, "random:", 7) ||
!strncmp(name, "ediff:", 6) ||
!strncmp(name, "bayer:", 6))
return pipi_load_stock(name);



+ 9
- 13
pipi/context.c Ver arquivo

@@ -84,19 +84,7 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
va_end(ap);
src = ctx->images[ctx->nimages - 1];
dst = NULL;
if(!strcmp(method, "fs"))
dst = pipi_dither_floydsteinberg(src, 0);
else if(!strcmp(method, "sfs"))
dst = pipi_dither_floydsteinberg(src, 1);
else if(!strcmp(method, "jajuni"))
dst = pipi_dither_jajuni(src, 0);
else if(!strcmp(method, "sjajuni"))
dst = pipi_dither_jajuni(src, 1);
else if(!strcmp(method, "atkinson"))
dst = pipi_dither_atkinson(src, 0);
else if(!strcmp(method, "satkinson"))
dst = pipi_dither_atkinson(src, 1);
else if(!strcmp(method, "ost"))
if(!strcmp(method, "ost"))
dst = pipi_dither_ostromoukhov(src, 0);
else if(!strcmp(method, "sost"))
dst = pipi_dither_ostromoukhov(src, 1);
@@ -108,6 +96,14 @@ int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
pipi_free(ctx->images[ctx->nimages - 2]);
ctx->nimages--;
}
else if(!strcmp(method, "sediff"))
{
if(ctx->nimages < 2)
return -1;
dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 1);
pipi_free(ctx->images[ctx->nimages - 2]);
ctx->nimages--;
}
else if(!strcmp(method, "ordered"))
{
if(ctx->nimages < 2)


+ 0
- 75
pipi/dither/atkinson.c Ver arquivo

@@ -1,75 +0,0 @@
/*
* libpipi Proper image processing implementation library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This library is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* atkinson.c: Atkinson dithering functions
*/

#include "config.h"
#include "common.h"

#include "pipi.h"
#include "pipi_internals.h"

pipi_image_t *pipi_dither_atkinson(pipi_image_t *img, pipi_scan_t scan)
{
pipi_image_t *dst;
pipi_pixels_t *dstp;
float *dstdata;
int x, y, w, h;

w = img->w;
h = img->h;

dst = pipi_copy(img);
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
dstdata = (float *)dstp->pixels;

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 = reverse ? w - 1 - x : x;
int s = reverse ? -1 : 1;

p = dstdata[y * w + x2];
q = p < 0.5 ? 0. : 1.;
dstdata[y * w + x2] = q;

e = (p - q) / 8.;
if(x < w - 1)
dstdata[y * w + x2 + s] += e;
if(x < w - 2)
dstdata[y * w + x2 + s + s] += e;
if(y < h - 1)
{
if(x > 0)
dstdata[(y + 1) * w + x2 - s] += e;
dstdata[(y + 1) * w + x2] += e;
if(x < w - 1)
dstdata[(y + 1) * w + x2 + s] += e;
}
if(y < h - 2)
{
dstdata[(y + 2) * w + x2] += e;
}
}
}

return dst;
}


+ 4
- 1
pipi/dither/ediff.c Ver arquivo

@@ -24,7 +24,10 @@

/* Perform a generic error diffusion dithering. The first non-zero
* element in ker is treated as the current pixel. All other non-zero
* elements are the error diffusion coefficients. */
* elements are the error diffusion coefficients.
* Making the matrix generic is not terribly slower: the performance
* hit is around 4% for Floyd-Steinberg and 13% for JaJuNi, with the
* benefit of a lot less code. */
pipi_image_t *pipi_dither_ediff(pipi_image_t *img, pipi_image_t *ker,
pipi_scan_t scan)
{


+ 0
- 71
pipi/dither/floydsteinberg.c Ver arquivo

@@ -1,71 +0,0 @@
/*
* libpipi Proper image processing implementation library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This library is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* floydsteinberg.c: Floyd-Steinberg dithering functions
*/

#include "config.h"
#include "common.h"

#include "pipi.h"
#include "pipi_internals.h"

pipi_image_t *pipi_dither_floydsteinberg(pipi_image_t *img, pipi_scan_t scan)
{
pipi_image_t *dst;
pipi_pixels_t *dstp;
float *dstdata;
int x, y, w, h;

w = img->w;
h = img->h;

dst = pipi_copy(img);
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
dstdata = (float *)dstp->pixels;

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 = reverse ? w - 1 - x : x;
int s = reverse ? -1 : 1;

p = dstdata[y * w + x2];
q = p < 0.5 ? 0. : 1.;
dstdata[y * w + x2] = q;

/* FIXME: according to our 2008 paper, [7 4 5 0] is a better
* error diffusion kernel for serpentine scan than [7 3 5 1]. */
e = (p - q) / 16;
if(x < w - 1)
dstdata[y * w + x2 + s] += e * 7;
if(y < h - 1)
{
if(x > 0)
dstdata[(y + 1) * w + x2 - s] += e * 3;
dstdata[(y + 1) * w + x2] += e * 5;
if(x < w - 1)
dstdata[(y + 1) * w + x2 + s] += e;
}
}
}

return dst;
}


+ 0
- 87
pipi/dither/jajuni.c Ver arquivo

@@ -1,87 +0,0 @@
/*
* libpipi Proper image processing implementation library
* Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This library is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* jajuni.c: Jarvis-Judice-Ninke dithering functions
*/

#include "config.h"
#include "common.h"

#include "pipi.h"
#include "pipi_internals.h"

pipi_image_t *pipi_dither_jajuni(pipi_image_t *img, pipi_scan_t scan)
{
pipi_image_t *dst;
pipi_pixels_t *dstp;
float *dstdata;
int x, y, w, h;

w = img->w;
h = img->h;

dst = pipi_copy(img);
dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
dstdata = (float *)dstp->pixels;

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 = reverse ? w - 1 - x : x;
int s = reverse ? -1 : 1;

p = dstdata[y * w + x2];
q = p < 0.5 ? 0. : 1.;
dstdata[y * w + x2] = q;

e = (p - q) / 48.;
if(x < w - 1)
dstdata[y * w + x2 + s] += e * 7;
if(x < w - 2)
dstdata[y * w + x2 + s + s] += e * 5;
if(y < h - 1)
{
if(x > 1)
dstdata[(y + 1) * w + x2 - s - s] += e * 3;
if(x > 0)
dstdata[(y + 1) * w + x2 - s] += e * 5;
dstdata[(y + 1) * w + x2] += e * 7;
if(x < w - 1)
dstdata[(y + 1) * w + x2 + s] += e * 5;
if(x < w - 2)
dstdata[(y + 1) * w + x2 + s + s] += e * 3;
}
if(y < h - 2)
{
if(x > 1)
dstdata[(y + 2) * w + x2 - s - s] += e;
if(x > 0)
dstdata[(y + 2) * w + x2 - s] += e * 3;
dstdata[(y + 2) * w + x2] += e * 5;
if(x < w - 1)
dstdata[(y + 2) * w + x2 + s] += e * 3;
if(x < w - 2)
dstdata[(y + 2) * w + x2 + s + s] += e;
}
}
}

return dst;
}


+ 0
- 3
pipi/pipi.h Ver arquivo

@@ -149,9 +149,6 @@ extern pipi_image_t *pipi_reduce(pipi_image_t *, int, double const *);

extern pipi_image_t *pipi_dither_ediff(pipi_image_t *, pipi_image_t *,
pipi_scan_t);
extern pipi_image_t *pipi_dither_floydsteinberg(pipi_image_t *, pipi_scan_t);
extern pipi_image_t *pipi_dither_jajuni(pipi_image_t *, pipi_scan_t);
extern pipi_image_t *pipi_dither_atkinson(pipi_image_t *, pipi_scan_t);
extern pipi_image_t *pipi_dither_ordered(pipi_image_t *, pipi_image_t *);
extern pipi_image_t *pipi_dither_random(pipi_image_t *);
extern pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *, pipi_scan_t);


+ 45
- 0
pipi/stock.c Ver arquivo

@@ -73,6 +73,51 @@ pipi_image_t *pipi_load_stock(char const *name)
return ret;
}

/* Generate an error diffusion matrix. */
if(!strncmp(name, "ediff:", 6))
{
float const *ker;
int w, h;

if(!strcmp(name + 6, "fs"))
{
static float const myker[] =
{
0., 1., 7./16,
3./16, 5./16, 1./16
};
ker = myker; w = 3; h = 2;
}
else if(!strcmp(name + 6, "jajuni"))
{
static float const myker[] =
{
0., 0., 1., 7./48, 5./48,
3./48, 5./48, 7./48, 5./48, 3./48,
1./48, 3./48, 5./48, 3./48, 1./48,
};
ker = myker; w = 5; h = 3;
}
else if(!strcmp(name + 6, "atkinson"))
{
static float const myker[] =
{
0., 1., 1./8, 1./8,
1./8, 1./8, 1./8, 0.,
0., 1./8, 0., 0.,
};
ker = myker; w = 4; h = 3;
}
else
return NULL;

ret = pipi_new(w, h);
pix = pipi_getpixels(ret, PIPI_PIXELS_Y_F);
memcpy(pix->pixels, ker, w * h * sizeof(float));

return ret;
}

/* Generate a completely random image. */
if(!strncmp(name, "random:", 7))
{


Carregando…
Cancelar
Salvar