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

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

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

File size: 3.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 * ordered.c: Bayer ordered dithering functions
17 */
18
19#include "config.h"
20
21#include <stdlib.h>
22#include <math.h>
23
24#include "pipi.h"
25#include "pipi_internals.h"
26
27pipi_image_t *pipi_dither_halftone(pipi_image_t *img, double r, double angle)
28{
29#define PRECISION 4.
30    pipi_image_t *ret, *kernel;
31    int k = (r * PRECISION / 2. / sqrt(2.) + .5);
32
33    kernel = pipi_render_halftone(k, k);
34    ret = pipi_dither_ordered_ext(img, kernel, 1. / PRECISION, angle + 45.);
35    pipi_free(kernel);
36
37    return ret;
38}
39
40pipi_image_t *pipi_dither_ordered(pipi_image_t *img, pipi_image_t *kernel)
41{
42    return pipi_dither_ordered_ext(img, kernel, 1.0, 0.0);
43}
44
45pipi_image_t *pipi_dither_ordered_ext(pipi_image_t *img, pipi_image_t *kernel,
46                                      double scale, double angle)
47{
48    double sint, cost;
49    pipi_image_t *dst;
50    pipi_pixels_t *dstp, *kernelp;
51    float *dstdata, *kerneldata;
52    int x, y, w, h, kx, ky, kw, kh;
53
54    w = img->w;
55    h = img->h;
56    kw = kernel->w;
57    kh = kernel->h;
58
59    cost = cos(angle * (M_PI / 180));
60    sint = sin(angle * (M_PI / 180));
61
62    dst = pipi_copy(img);
63    dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
64    dstdata = (float *)dstp->pixels;
65
66    kernelp = pipi_getpixels(kernel, PIPI_PIXELS_Y_F);
67    kerneldata = (float *)kernelp->pixels;
68
69    for(y = 0; y < h; y++)
70    {
71        for(x = 0; x < w; x++)
72        {
73            float p, q;
74
75            kx = (int)((cost * x - sint * y + 2 * w * h) / scale) % kw;
76            ky = (int)((cost * y + sint * x + 2 * w * h) / scale) % kh;
77
78            p = dstdata[y * w + x];
79            q = p > kerneldata[ky * kw + kx] ? 1. : 0.;
80            dstdata[y * w + x] = q;
81        }
82    }
83
84    return dst;
85}
86
87typedef struct
88{
89    int x, y;
90    double val;
91}
92dot_t;
93
94static int cmpdot(const void *p1, const void *p2)
95{
96    return ((dot_t const *)p1)->val > ((dot_t const *)p2)->val;
97}
98
99pipi_image_t *pipi_order(pipi_image_t *src)
100{
101    double epsilon;
102    pipi_image_t *dst;
103    pipi_pixels_t *dstp, *srcp;
104    float *dstdata, *srcdata;
105    dot_t *circle;
106    int x, y, w, h, n;
107
108    w = src->w;
109    h = src->h;
110    epsilon = 1. / (w * h + 1);
111
112    srcp = pipi_getpixels(src, PIPI_PIXELS_Y_F);
113    srcdata = (float *)srcp->pixels;
114
115    dst = pipi_new(w, h);
116    dstp = pipi_getpixels(dst, PIPI_PIXELS_Y_F);
117    dstdata = (float *)dstp->pixels;
118
119    circle = malloc(w * h * sizeof(dot_t));
120
121    for(y = 0; y < h; y++)
122        for(x = 0; x < w; x++)
123        {
124            circle[y * w + x].x = x;
125            circle[y * w + x].y = y;
126            circle[y * w + x].val = srcdata[y * w + x];
127        }
128    qsort(circle, w * h, sizeof(dot_t), cmpdot);
129
130    for(n = 0; n < w * h; n++)
131    {
132        x = circle[n].x;
133        y = circle[n].y;
134        dstdata[y * w + x] = (float)(n + 1) * epsilon;
135    }
136
137    free(circle);
138
139    return dst;
140}
141
Note: See TracBrowser for help on using the repository browser.