source: libpipi/trunk/pipi/filter/color.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: 7.7 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 * color.c: colour manipulation functions
17 */
18
19#include "config.h"
20
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <math.h>
25
26#include "pipi.h"
27#include "pipi_internals.h"
28
29pipi_image_t *pipi_brightness(pipi_image_t *src, double val)
30{
31    pipi_image_t *dst;
32    pipi_pixels_t *srcp, *dstp;
33    float *srcdata, *dstdata;
34    int x, y, w, h, gray;
35
36    w = src->w;
37    h = src->h;
38
39    gray = (src->last_modified == PIPI_PIXELS_Y_F);
40
41    srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
42                : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
43    srcdata = (float *)srcp->pixels;
44
45    dst = pipi_new(w, h);
46    dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
47                : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
48    dstdata = (float *)dstp->pixels;
49
50    if(val >= 0.0)
51    {
52        for(y = 0; y < h; y++)
53        {
54            for(x = 0; x < w; x++)
55            {
56                if(gray)
57                {
58                    double p = srcdata[y * w + x];
59                    dstdata[y * w + x] = p < 1. - val ? p + val : 1.;
60                }
61                else
62                {
63                    double p;
64                    int d = 4 * (y * w + x);
65
66                    p = srcdata[d];
67                    dstdata[d] = p < 1. - val ? p + val : 1.;
68                    p = srcdata[d + 1];
69                    dstdata[d + 1] = p < 1. - val ? p + val : 1.;
70                    p = srcdata[d + 2];
71                    dstdata[d + 2] = p < 1. - val ? p + val : 1.;
72                    p = srcdata[d + 3];
73                    dstdata[d + 3] = p < 1. - val ? p + val : 1.;
74                }
75            }
76        }
77    }
78    else
79    {
80        for(y = 0; y < h; y++)
81        {
82            for(x = 0; x < w; x++)
83            {
84                if(gray)
85                {
86                    double p = srcdata[y * w + x];
87                    dstdata[y * w + x] = p > -val ? p + val : 0.;
88                }
89                else
90                {
91                    double p;
92                    int d = 4 * (y * w + x);
93
94                    p = srcdata[d];
95                    dstdata[d] = p > -val ? p + val : 0.;
96                    p = srcdata[d + 1];
97                    dstdata[d + 1] = p > -val ? p + val : 0.;
98                    p = srcdata[d + 2];
99                    dstdata[d + 2] = p > -val ? p + val : 0.;
100                    p = srcdata[d + 3];
101                    dstdata[d + 3] = p > -val ? p + val : 0.;
102                }
103            }
104        }
105    }
106
107    return dst;
108}
109
110pipi_image_t *pipi_contrast(pipi_image_t *src, double val)
111{
112    pipi_image_t *dst;
113    pipi_pixels_t *srcp, *dstp;
114    float *srcdata, *dstdata;
115    int x, y, w, h, gray;
116
117    w = src->w;
118    h = src->h;
119
120    gray = (src->last_modified == PIPI_PIXELS_Y_F);
121
122    srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
123                : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
124    srcdata = (float *)srcp->pixels;
125
126    dst = pipi_new(w, h);
127    dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
128                : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
129    dstdata = (float *)dstp->pixels;
130
131    if(val >= 0.0)
132    {
133        if(val > 0.99999)
134            val = 0.99999;
135
136        val = 1. / (1. - val);
137
138        for(y = 0; y < h; y++)
139        {
140            for(x = 0; x < w; x++)
141            {
142                if(gray)
143                {
144                    double p = (srcdata[y * w + x] - 0.5) * val + 0.5;
145                    dstdata[y * w + x] = p < 0. ? 0. : p > 1. ? 1. : p;
146                }
147                else
148                {
149                    double p;
150                    int d = 4 * (y * w + x);
151
152                    p = (srcdata[d] - 0.5) * val + 0.5;
153                    dstdata[d] = p < 0. ? 0. : p > 1. ? 1. : p;
154                    p = (srcdata[d + 1] - 0.5) * val + 0.5;
155                    dstdata[d + 1] = p < 0. ? 0. : p > 1. ? 1. : p;
156                    p = (srcdata[d + 2] - 0.5) * val + 0.5;
157                    dstdata[d + 2] = p < 0. ? 0. : p > 1. ? 1. : p;
158                    p = (srcdata[d + 3] - 0.5) * val + 0.5;
159                    dstdata[d + 3] = p < 0. ? 0. : p > 1. ? 1. : p;
160                }
161            }
162        }
163    }
164    else
165    {
166        if(val < -1.)
167            val = -1.;
168
169        val = 1. + val;
170
171        for(y = 0; y < h; y++)
172        {
173            for(x = 0; x < w; x++)
174            {
175                if(gray)
176                {
177                    double p = srcdata[y * w + x];
178                    dstdata[y * w + x] = (p - 0.5) * val + 0.5;
179                }
180                else
181                {
182                    double p;
183                    int d = 4 * (y * w + x);
184
185                    p = srcdata[d];
186                    dstdata[d] = (p - 0.5) * val + 0.5;
187                    p = srcdata[d + 1];
188                    dstdata[d + 1] = (p - 0.5) * val + 0.5;
189                    p = srcdata[d + 2];
190                    dstdata[d + 2] = (p - 0.5) * val + 0.5;
191                    p = srcdata[d + 3];
192                    dstdata[d + 3] = (p - 0.5) * val + 0.5;
193                }
194            }
195        }
196    }
197
198    return dst;
199}
200
201pipi_image_t *pipi_invert(pipi_image_t *src)
202{
203    pipi_image_t *dst;
204    pipi_pixels_t *srcp, *dstp;
205    float *srcdata, *dstdata;
206    int x, y, w, h, gray;
207
208    w = src->w;
209    h = src->h;
210
211    gray = (src->last_modified == PIPI_PIXELS_Y_F);
212
213    srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
214                : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
215    srcdata = (float *)srcp->pixels;
216
217    dst = pipi_new(w, h);
218    dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
219                : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
220    dstdata = (float *)dstp->pixels;
221
222    for(y = 0; y < h; y++)
223    {
224        for(x = 0; x < w; x++)
225        {
226            if(gray)
227            {
228                dstdata[y * w + x] = 1. - srcdata[y * w + x];
229            }
230            else
231            {
232                int d = 4 * (y * w + x);
233
234                dstdata[d] = 1. - srcdata[d];
235                dstdata[d + 1] = 1. - srcdata[d + 1];
236                dstdata[d + 2] = 1. - srcdata[d + 2];
237                dstdata[d + 3] = 1. - srcdata[d + 3];
238            }
239        }
240    }
241
242    return dst;
243}
244
245pipi_image_t *pipi_threshold(pipi_image_t *src, double val)
246{
247    pipi_image_t *dst;
248    pipi_pixels_t *srcp, *dstp;
249    float *srcdata, *dstdata;
250    int x, y, w, h, gray;
251
252    w = src->w;
253    h = src->h;
254
255    gray = (src->last_modified == PIPI_PIXELS_Y_F);
256
257    srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
258                : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
259    srcdata = (float *)srcp->pixels;
260
261    dst = pipi_new(w, h);
262    dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
263                : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
264    dstdata = (float *)dstp->pixels;
265
266    for(y = 0; y < h; y++)
267    {
268        for(x = 0; x < w; x++)
269        {
270            if(gray)
271            {
272                dstdata[y * w + x] = srcdata[y * w + x] < val ? 0. : 1.;
273            }
274            else
275            {
276                int d = 4 * (y * w + x);
277
278                dstdata[d] = srcdata[d] < val ? 0. : 1.;
279                dstdata[d + 1] = srcdata[d + 1] < val ? 0. : 1.;
280                dstdata[d + 2] = srcdata[d + 2] < val ? 0. : 1.;
281                dstdata[d + 3] = srcdata[d + 3] < val ? 0. : 1.;
282            }
283        }
284    }
285
286    return dst;
287}
288
Note: See TracBrowser for help on using the repository browser.