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

Last change on this file was 3342, checked in by Sam Hocevar, 11 years ago

Change _C pixel format suffixes into _U8 for more clarity.

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
21#include "pipi.h"
22#include "pipi_internals.h"
23
24/* Perform a generic error diffusion dithering. The first non-zero
25 * element in ker is treated as the current pixel. All other non-zero
26 * elements are the error diffusion coefficients.
27 * Making the matrix generic is not terribly slower: the performance
28 * hit is around 4% for Floyd-Steinberg and 13% for JaJuNi, with the
29 * benefit of a lot less code. */
30pipi_image_t *pipi_dither_ediff(pipi_image_t *img, pipi_image_t *ker,
31                                pipi_scan_t scan)
32{
33    pipi_image_t *dst;
34    pipi_pixels_t *dstp, *kerp;
35    float *dstdata, *kerdata;
36    int x, y, w, h, i, j, kx, kw, kh;
37
38    w = img->w;
39    h = img->h;
40    kw = ker->w;
41    kh = ker->h;
42
43    dst = pipi_copy(img);
44    dstp = pipi_get_pixels(dst, PIPI_PIXELS_Y_F32);
45    dstdata = (float *)dstp->pixels;
46
47    kerp = pipi_get_pixels(ker, PIPI_PIXELS_Y_F32);
48    kerdata = (float *)kerp->pixels;
49    for(kx = 0; kx < kw; kx++)
50        if(kerdata[kx] > 0)
51            break;
52
53    for(y = 0; y < h; y++)
54    {
55        int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE);
56
57        for(x = 0; x < w; x++)
58        {
59            float p, q, e;
60            int x2 = reverse ? w - 1 - x : x;
61            int s = reverse ? -1 : 1;
62
63            p = dstdata[y * w + x2];
64            q = p < 0.5 ? 0. : 1.;
65            dstdata[y * w + x2] = q;
66
67            e = (p - q);
68
69            for(j = 0; j < kh && y < h - j; j++)
70                for(i = 0; i < kw; i++)
71                {
72                    if(j == 0 && i <= kx)
73                        continue;
74
75                    if(x + i - kx < 0 || x + i - kx >= w)
76                        continue;
77
78                    dstdata[(y + j) * w + x2 + (i - kx) * s]
79                       += e * kerdata[j * kw + i];
80                }
81        }
82    }
83
84    return dst;
85}
86
Note: See TracBrowser for help on using the repository browser.