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

Last change on this file was 3342, checked in by Sam Hocevar, 10 years ago

Change _C pixel format suffixes into _U8 for more clarity.

File size: 5.0 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 * dilate.c: dilate and erode 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
29/* FIXME: these functions are almost the same, try to merge them
30 * somewhat efficiently. */
31/* TODO: - dilate by k (Manhattan distance)
32 *       - dilate by r (euclidian distance, with non-integer r) */
33pipi_image_t *pipi_dilate(pipi_image_t *src)
34{
35    pipi_image_t *dst;
36    pipi_pixels_t *srcp, *dstp;
37    float *srcdata, *dstdata;
38    int x, y, w, h, i, gray;
39
40    w = src->w;
41    h = src->h;
42
43    gray = (src->last_modified == PIPI_PIXELS_Y_F32);
44
45    srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
46                : pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
47    srcdata = (float *)srcp->pixels;
48
49    dst = pipi_new(w, h);
50    dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
51                : pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
52    dstdata = (float *)dstp->pixels;
53
54    for(y = 0; y < h; y++)
55    {
56        for(x = 0; x < w; x++)
57        {
58            double t;
59            int x2, y2, x3, y3;
60
61            y2 = y - 1;
62            if(y2 < 0) y2 = h - 1;
63            y3 = y + 1;
64            if(y3 >= h) y3 = 0;
65
66            x2 = x - 1;
67            if(x2 < 0) x2 = w - 1;
68            x3 = x + 1;
69            if(x3 >= w) x3 = 0;
70
71            if(gray)
72            {
73                t = srcdata[y * w + x];
74                if(srcdata[y2 * w + x] > t) t = srcdata[y2 * w + x];
75                if(srcdata[y3 * w + x] > t) t = srcdata[y3 * w + x];
76                if(srcdata[y * w + x2] > t) t = srcdata[y * w + x2];
77                if(srcdata[y * w + x3] > t) t = srcdata[y * w + x3];
78                dstdata[y * w + x] = t;
79            }
80            else
81            {
82                for(i = 0; i < 4; i++)
83                {
84                    t = srcdata[4 * (y * w + x) + i];
85                    if(srcdata[4 * (y2 * w + x) + i] > t)
86                        t = srcdata[4 * (y2 * w + x) + i];
87                    if(srcdata[4 * (y3 * w + x) + i] > t)
88                        t = srcdata[4 * (y3 * w + x) + i];
89                    if(srcdata[4 * (y * w + x2) + i] > t)
90                        t = srcdata[4 * (y * w + x2) + i];
91                    if(srcdata[4 * (y * w + x3) + i] > t)
92                        t = srcdata[4 * (y * w + x3) + i];
93                    dstdata[4 * (y * w + x) + i] = t;
94                }
95            }
96        }
97    }
98
99    return dst;
100}
101
102pipi_image_t *pipi_erode(pipi_image_t *src)
103{
104    pipi_image_t *dst;
105    pipi_pixels_t *srcp, *dstp;
106    float *srcdata, *dstdata;
107    int x, y, w, h, i, gray;
108
109    w = src->w;
110    h = src->h;
111
112    gray = (src->last_modified == PIPI_PIXELS_Y_F32);
113
114    srcp = gray ? pipi_get_pixels(src, PIPI_PIXELS_Y_F32)
115                : pipi_get_pixels(src, PIPI_PIXELS_RGBA_F32);
116    srcdata = (float *)srcp->pixels;
117
118    dst = pipi_new(w, h);
119    dstp = gray ? pipi_get_pixels(dst, PIPI_PIXELS_Y_F32)
120                : pipi_get_pixels(dst, PIPI_PIXELS_RGBA_F32);
121    dstdata = (float *)dstp->pixels;
122
123    for(y = 0; y < h; y++)
124    {
125        for(x = 0; x < w; x++)
126        {
127            double t;
128            int x2, y2, x3, y3;
129
130            y2 = y - 1;
131            if(y2 < 0) y2 = h - 1;
132            y3 = y + 1;
133            if(y3 >= h) y3 = 0;
134
135            x2 = x - 1;
136            if(x2 < 0) x2 = w - 1;
137            x3 = x + 1;
138            if(x3 >= w) x3 = 0;
139
140            if(gray)
141            {
142                t = srcdata[y * w + x];
143                if(srcdata[y2 * w + x] < t) t = srcdata[y2 * w + x];
144                if(srcdata[y3 * w + x] < t) t = srcdata[y3 * w + x];
145                if(srcdata[y * w + x2] < t) t = srcdata[y * w + x2];
146                if(srcdata[y * w + x3] < t) t = srcdata[y * w + x3];
147                dstdata[y * w + x] = t;
148            }
149            else
150            {
151                for(i = 0; i < 4; i++)
152                {
153                    t = srcdata[4 * (y * w + x) + i];
154                    if(srcdata[4 * (y2 * w + x) + i] < t)
155                        t = srcdata[4 * (y2 * w + x) + i];
156                    if(srcdata[4 * (y3 * w + x) + i] < t)
157                        t = srcdata[4 * (y3 * w + x) + i];
158                    if(srcdata[4 * (y * w + x2) + i] < t)
159                        t = srcdata[4 * (y * w + x2) + i];
160                    if(srcdata[4 * (y * w + x3) + i] < t)
161                        t = srcdata[4 * (y * w + x3) + i];
162                    dstdata[4 * (y * w + x) + i] = t;
163                }
164            }
165        }
166    }
167
168    return dst;
169}
170
Note: See TracBrowser for help on using the repository browser.