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