source: libpipi/trunk/pipi/dither/ediff.c @ 2844

Last change on this file since 2844 was 2844, checked in by Sam Hocevar, 12 years ago

Fix headers.

File size: 2.4 KB
Line 
1/*
2 *  libpipi       Pathetic image processing interface library
3 *  Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id$
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 * ed.c: generic error diffusion functions
17 */
18
19#include "config.h"
20#include "common.h"
21
22#include "pipi.h"
23#include "pipi_internals.h"
24
25/* Perform a generic error diffusion dithering. The first non-zero
26 * element in ker is treated as the current pixel. All other non-zero
27 * elements are the error diffusion coefficients.
28 * Making the matrix generic is not terribly slower: the performance
29 * hit is around 4% for Floyd-Steinberg and 13% for JaJuNi, with the
30 * benefit of a lot less code. */
31pipi_image_t *pipi_dither_ediff(pipi_image_t *img, pipi_image_t *ker,
32                                pipi_scan_t scan)
33{
34    pipi_image_t *dst;
35    pipi_pixels_t *dstp, *kerp;
36    float *dstdata, *kerdata;
37    int x, y, w, h, i, j, kx, kw, kh;
38
39    w = img->w;
40    h = img->h;
41    kw = ker->w;
42    kh = ker->h;
43
44    dst = pipi_copy(img);
45    dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
46    dstdata = (float *)dstp->pixels;
47
48    kerp = pipi_getpixels(ker, PIPI_PIXELS_Y_F);
49    kerdata = (float *)kerp->pixels;
50    for(kx = 0; kx < kw; kx++)
51        if(kerdata[kx] > 0)
52            break;
53
54    for(y = 0; y < h; y++)
55    {
56        int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE);
57
58        for(x = 0; x < w; x++)
59        {
60            float p, q, e;
61            int x2 = reverse ? w - 1 - x : x;
62            int s = reverse ? -1 : 1;
63
64            p = dstdata[y * w + x2];
65            q = p < 0.5 ? 0. : 1.;
66            dstdata[y * w + x2] = q;
67
68            e = (p - q);
69
70            for(j = 0; j < kh && y < h - j; j++)
71                for(i = 0; i < kw; i++)
72                {
73                    if(j == 0 && i <= kx)
74                        continue;
75
76                    if(x + i - kx < 0 || x + i - kx >= w)
77                        continue;
78
79                    dstdata[(y + j) * w + x2 + (i - kx) * s]
80                       += e * kerdata[j * kw + i];
81                }
82        }
83    }
84
85    return dst;
86}
87
Note: See TracBrowser for help on using the repository browser.