source: libpipi/trunk/pipi/filter/color.c

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

Do not touch the alpha layer in pipi_contrast().

File size: 7.6 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_F32);
40
41    srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
42                : pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
43    srcdata = (float *)srcp->pixels;
44
45    dst = pipi_new(w, h);
46    dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
47                : pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
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;
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;
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_F32);
121
122    srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
123                : pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
124    srcdata = (float *)srcp->pixels;
125
126    dst = pipi_new(w, h);
127    dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
128                : pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
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];
159                    dstdata[d + 3] = 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;
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_F32);
212
213    srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
214                : pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
215    srcdata = (float *)srcp->pixels;
216
217    dst = pipi_new(w, h);
218    dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
219                : pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
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_F32);
256
257    srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
258                : pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
259    srcdata = (float *)srcp->pixels;
260
261    dst = pipi_new(w, h);
262    dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
263                : pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
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.