source: libpipi/trunk/pipi/dither/ostromoukhov.c @ 2902

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

Support C99 types on Win32 through the same hacks as in libcaca.

File size: 4.3 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 * ostromoukhov.c: Ostromoukhov dithering functions
17 *
18 * This module implements Ostromoukhov's simple error diffusion algorithm,
19 * as introduced in the paper "A Simple and Efficient Error-Diffusion
20 * Algorithm", Proceedings of SIGGRAPH 2001, in ACM Computer Graphics,
21 * Annual Conference Series, pp. 567--572, 2001.
22 *
23 * TODO: the table is actually a piecewise linear function, so it should
24 * be easy to change it into something that works perfectly with floats.
25 */
26
27#include "config.h"
28
29#include "pipi.h"
30#include "pipi_internals.h"
31
32static int const table[][3] =
33{
34     {13, 0, 5}, {13, 0, 5}, {21, 0, 10}, {7, 0, 4},
35     {8, 0, 5}, {47, 3, 28}, {23, 3, 13}, {15, 3, 8},
36     {22, 6, 11}, {43, 15, 20}, {7, 3, 3}, {501, 224, 211},
37     {249, 116, 103}, {165, 80, 67}, {123, 62, 49}, {489, 256, 191},
38     {81, 44, 31}, {483, 272, 181}, {60, 35, 22}, {53, 32, 19},
39     {237, 148, 83}, {471, 304, 161}, {3, 2, 1}, {481, 314, 185},
40     {354, 226, 155}, {1389, 866, 685}, {227, 138, 125}, {267, 158, 163},
41     {327, 188, 220}, {61, 34, 45}, {627, 338, 505}, {1227, 638, 1075},
42     {20, 10, 19}, {1937, 1000, 1767}, {977, 520, 855}, {657, 360, 551},
43     {71, 40, 57}, {2005, 1160, 1539}, {337, 200, 247}, {2039, 1240, 1425},
44     {257, 160, 171}, {691, 440, 437}, {1045, 680, 627}, {301, 200, 171},
45     {177, 120, 95}, {2141, 1480, 1083}, {1079, 760, 513}, {725, 520, 323},
46     {137, 100, 57}, {2209, 1640, 855}, {53, 40, 19}, {2243, 1720, 741},
47     {565, 440, 171}, {759, 600, 209}, {1147, 920, 285}, {2311, 1880, 513},
48     {97, 80, 19}, {335, 280, 57}, {1181, 1000, 171}, {793, 680, 95},
49     {599, 520, 57}, {2413, 2120, 171}, {405, 360, 19}, {2447, 2200, 57},
50     {11, 10, 0}, {158, 151, 3}, {178, 179, 7}, {1030, 1091, 63},
51     {248, 277, 21}, {318, 375, 35}, {458, 571, 63}, {878, 1159, 147},
52     {5, 7, 1}, {172, 181, 37}, {97, 76, 22}, {72, 41, 17},
53     {119, 47, 29}, {4, 1, 1}, {4, 1, 1}, {4, 1, 1},
54     {4, 1, 1}, {4, 1, 1}, {4, 1, 1}, {4, 1, 1},
55     {4, 1, 1}, {4, 1, 1}, {65, 18, 17}, {95, 29, 26},
56     {185, 62, 53}, {30, 11, 9}, {35, 14, 11}, {85, 37, 28},
57     {55, 26, 19}, {80, 41, 29}, {155, 86, 59}, {5, 3, 2},
58     {5, 3, 2}, {5, 3, 2}, {5, 3, 2}, {5, 3, 2},
59     {5, 3, 2}, {5, 3, 2}, {5, 3, 2}, {5, 3, 2},
60     {5, 3, 2}, {5, 3, 2}, {5, 3, 2}, {5, 3, 2},
61     {305, 176, 119}, {155, 86, 59}, {105, 56, 39}, {80, 41, 29},
62     {65, 32, 23}, {55, 26, 19}, {335, 152, 113}, {85, 37, 28},
63     {115, 48, 37}, {35, 14, 11}, {355, 136, 109}, {30, 11, 9},
64     {365, 128, 107}, {185, 62, 53}, {25, 8, 7}, {95, 29, 26},
65     {385, 112, 103}, {65, 18, 17}, {395, 104, 101}, {4, 1, 1}
66};
67
68pipi_image_t *pipi_dither_ostromoukhov(pipi_image_t *img, pipi_scan_t scan)
69{
70    pipi_image_t *dst;
71    pipi_pixels_t *dstp;
72    float *dstdata;
73    int x, y, w, h;
74
75    w = img->w;
76    h = img->h;
77
78    dst = pipi_copy(img);
79    dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
80    dstdata = (float *)dstp->pixels;
81
82    for(y = 0; y < h; y++)
83    {
84        int reverse = (y & 1) && (scan == PIPI_SCAN_SERPENTINE);
85
86        for(x = 0; x < w; x++)
87        {
88            float p, q, e;
89            int x2, s, i;
90
91            x2 = reverse ? w - 1 - x : x;
92            s = reverse ? -1 : 1;
93
94            p = dstdata[y * w + x2];
95            q = p < 0.5 ? 0. : 1.;
96            dstdata[y * w + x2] = q;
97
98            e = p - q;
99            i = p * 255.9999;
100            if(i > 127) i = 255 - i;
101            if(i < 0) i = 0; /* XXX: no "else" here */
102            e /= table[i][0] + table[i][1] + table[i][2];
103
104            if(x < w - 1)
105                dstdata[y * w + x2 + s] += e * table[i][0];
106            if(y < h - 1)
107            {
108                if(x > 0)
109                    dstdata[(y + 1) * w + x2 - s] += e * table[i][1];
110                dstdata[(y + 1) * w + x2] += e * table[i][2];
111            }
112        }
113    }
114
115    return dst;
116}
117
Note: See TracBrowser for help on using the repository browser.