source: libpipi/trunk/pipi/render/screen.c @ 2844

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

Fix headers.

File size: 2.9 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 * screen.c: halftoning screen functions
17 */
18
19#include "config.h"
20#include "common.h"
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <math.h>
26
27#include "pipi.h"
28#include "pipi_internals.h"
29
30pipi_image_t *pipi_render_bayer(int w, int h)
31{
32    pipi_image_t *ret;
33    pipi_pixels_t *pix;
34    float *data;
35    int i, j, n;
36
37    if(w <= 0 || h <= 0)
38        return NULL;
39
40    for(n = 1; n < w || n < h; n *= 2)
41        ;
42
43    ret = pipi_new(w, h);
44    pix = pipi_getpixels(ret, PIPI_PIXELS_Y_F);
45    data = (float *)pix->pixels;
46
47    for(j = 0; j < h; j++)
48        for(i = 0; i < w; i++)
49        {
50            int k, l, x = 0;
51
52            for(k = 1, l = n * n / 4; k < n; k *= 2, l /= 4)
53            {
54                if((i & k) && (j & k))
55                    x += l;
56                else if(i & k)
57                    x += 3 * l;
58                else if(j & k)
59                    x += 2 * l;
60            }
61
62            data[j * w + i] = (double)(x + 1) / (n * n + 1);
63        }
64
65    return ret;
66}
67
68typedef struct
69{
70    int x, y;
71    double dist;
72}
73dot_t;
74
75static int cmpdot(const void *p1, const void *p2)
76{
77    return ((dot_t const *)p1)->dist > ((dot_t const *)p2)->dist;
78}
79
80pipi_image_t *pipi_render_halftone(int w, int h)
81{
82    pipi_image_t *ret;
83    pipi_pixels_t *pix;
84    float *data;
85    dot_t *circle;
86    int x, y, n;
87
88    if(w <= 0 || h <= 0)
89        return NULL;
90
91    circle = malloc(w * h * sizeof(dot_t));
92
93    for(y = 0; y < h; y++)
94        for(x = 0; x < w; x++)
95        {
96            double dy = ((double)y + .07) / h - .5;
97            double dx = (double)x / w - .5;
98            /* Using dx²+dy² here creates another interesting halftone. */
99            double r = - cos(M_PI * (dx - dy)) - cos(M_PI * (dx + dy));
100            circle[y * w + x].x = x;
101            circle[y * w + x].y = y;
102            circle[y * w + x].dist = r;
103        }
104    qsort(circle, w * h, sizeof(dot_t), cmpdot);
105
106    ret = pipi_new(w * 2, h * 2);
107    pix = pipi_getpixels(ret, PIPI_PIXELS_Y_F);
108    data = (float *)pix->pixels;
109
110    for(n = 0; n < w * h; n++)
111    {
112        x = circle[n].x;
113        y = circle[n].y;
114
115        data[y * (2 * w) + x] = (float)(2 * n + 1) / (w * h * 4 + 1);
116        data[(y + h) * (2 * w) + x + w] = (float)(2 * n + 2) / (w * h * 4 + 1);
117        data[(y + h) * (2 * w) + x] = 1. - (float)(2 * n + 1) / (w * h * 4 + 1);
118        data[y * (2 * w) + x + w] = 1. - (float)(2 * n + 2) / (w * h * 4 + 1);
119    }
120
121    free(circle);
122
123    return ret;
124}
125
Note: See TracBrowser for help on using the repository browser.