1 /*
2  * Copyright (c) 2011, Tom Distler (http://tdistler.com)
3  * All rights reserved.
4  *
5  * The BSD License
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  *
13  * - Redistributions in binary form must reproduce the above copyright notice,
14  *   this list of conditions and the following disclaimer in the documentation
15  *   and/or other materials provided with the distribution.
16  *
17  * - Neither the name of the tdistler.com nor the names of its contributors may
18  *   be used to endorse or promote products derived from this software without
19  *   specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef _CONVOLVE_H_
35 #define _CONVOLVE_H_
36 
37 typedef float (*_iqa_get_pixel)(const float *img, int w, int h, int x, int y, float bnd_const);
38 
39 /** Out-of-bounds array values are a mirrored reflection of the border values*/
40 float KBND_SYMMETRIC(const float *img, int w, int h, int x, int y, float bnd_const);
41 /** Out-of-bounds array values are set to the nearest border value */
42 float KBND_REPLICATE(const float *img, int w, int h, int x, int y, float bnd_const);
43 /** Out-of-bounds array values are set to 'bnd_const' */
44 float KBND_CONSTANT(const float *img, int w, int h, int x, int y, float bnd_const);
45 
46 
47 /** Defines a convolution kernel */
48 struct _kernel {
49     float *kernel;          /**< Pointer to the kernel values */
50     int w;                  /**< The kernel width */
51     int h;                  /**< The kernel height */
52     int normalized;         /**< 1 if the kernel values add up to 1. 0 otherwise */
53     _iqa_get_pixel bnd_opt; /**< Defines how out-of-bounds image values are handled */
54     float bnd_const;        /**< If 'bnd_opt' is KBND_CONSTANT, this specifies the out-of-bounds value */
55 };
56 
57 /**
58  * @brief Applies the specified kernel to the image.
59  * The kernel will be applied to all areas where it fits completely within
60  * the image. The resulting image will be smaller by half the kernel width
61  * and height (w - kw/2 and h - kh/2).
62  *
63  * @param img Image to modify
64  * @param w Image width
65  * @param h Image height
66  * @param k The kernel to apply
67  * @param result Buffer to hold the resulting image ((w-kw)*(h-kh), where kw
68  *               and kh are the kernel width and height). If 0, the result
69  *               will be written to the original image buffer.
70  * @param rw Optional. The width of the resulting image will be stored here.
71  * @param rh Optional. The height of the resulting image will be stored here.
72  */
73 void _iqa_convolve(float *img, int w, int h, const struct _kernel *k, float *result, int *rw, int *rh);
74 
75 /**
76  * The same as _iqa_convolve() except the kernel is applied to the entire image.
77  * In other words, the kernel is applied to all areas where the top-left corner
78  * of the kernel is in the image. Out-of-bound pixel value (off the right and
79  * bottom edges) are chosen based on the 'bnd_opt' and 'bnd_const' members of
80  * the kernel structure. The resulting array is the same size as the input
81  * image.
82  *
83  * @param img Image to modify
84  * @param w Image width
85  * @param h Image height
86  * @param k The kernel to apply
87  * @param result Buffer to hold the resulting image ((w-kw)*(h-kh), where kw
88  *               and kh are the kernel width and height). If 0, the result
89  *               will be written to the original image buffer.
90  * @return 0 if successful. Non-zero otherwise.
91  */
92 int _iqa_img_filter(float *img, int w, int h, const struct _kernel *k, float *result);
93 
94 /**
95  * Returns the filtered version of the specified pixel. If no kernel is given,
96  * the raw pixel value is returned.
97  *
98  * @param img Source image
99  * @param w Image width
100  * @param h Image height
101  * @param x The x location of the pixel to filter
102  * @param y The y location of the pixel to filter
103  * @param k Optional. The convolution kernel to apply to the pixel.
104  * @param kscale The scale of the kernel (for normalization). 1 for normalized
105  *               kernels. Required if 'k' is not null.
106  * @return The filtered pixel value.
107  */
108 float _iqa_filter_pixel(const float *img, int w, int h, int x, int y, const struct _kernel *k, const float kscale);
109 
110 
111 #endif /*_CONVOLVE_H_*/
112