1/*
2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27/*
28 * FUNCTION
29 * mlib_ImageClipping
30 * mlib_ImageClippingMxN
31 * Clipping for image processing in case of pixel-to-pixel
32 * square kernel filtering. Source and destination images can have
33 * different sizes, center of the source is mapped to the center of
34 * the destination image.
35 * Examples of this type of image processing are Convolve, Gradient,
36 * Dilate/Erode functions, etc.
37 *
38 * SYNOPSIS
39 * mlib_status mlib_ImageClipping(mlib_image *dst_i,
40 * mlib_image *src_i,
41 * mlib_image *dst_e,
42 * mlib_image *src_e,
43 * mlib_s32 *edg_sizes,
44 * const mlib_image *dst,
45 * const mlib_image *src,
46 * mlib_s32 ker_size)
47 *
48 * mlib_status mlib_ImageClippingMxN(mlib_image *dst_i,
49 * mlib_image *src_i,
50 * mlib_image *dst_e,
51 * mlib_image *src_e,
52 * mlib_s32 *edg_sizes,
53 * const mlib_image *dst,
54 * const mlib_image *src,
55 * mlib_s32 kw,
56 * mlib_s32 kh,
57 * mlib_s32 kw1,
58 * mlib_s32 kh1)
59 *
60 * OUTPUT ARGUMENTS
61 * dst_i Pointer to destination image of internal pixels
62 * src_i Pointer to source image of internal pixels
63 * dst_e Pointer to destination image for edge processing
64 * src_e Pointer to source image for edge processing
65 * edg_sizes Array of edge sizes
66 *
67 * INPUT ARGUMENTS
68 * dst Pointer to destination image.
69 * src Pointer to source image.
70 * ksize Size of kernel
71 *
72 * RESTRICTION
73 * The src and the dst must be images of the same type.
74 * The src and dst must have same number of channels.
75 *
76 */
77
78#include "mlib_image.h"
79#include "mlib_ImageCheck.h"
80#include "mlib_ImageClipping.h"
81#include "mlib_ImageCreate.h"
82
83/***************************************************************/
84mlib_status mlib_ImageClippingMxN(mlib_image *dst_i,
85 mlib_image *src_i,
86 mlib_image *dst_e,
87 mlib_image *src_e,
88 mlib_s32 *edg_sizes,
89 const mlib_image *dst,
90 const mlib_image *src,
91 mlib_s32 kw,
92 mlib_s32 kh,
93 mlib_s32 kw1,
94 mlib_s32 kh1)
95{
96 mlib_s32 kw2 = kw - 1 - kw1;
97 mlib_s32 kh2 = kh - 1 - kh1;
98 mlib_s32 src_wid, src_hgt, dst_wid, dst_hgt;
99 mlib_s32 dx, dy, dxd, dxs, dyd, dys, wid_e, hgt_e;
100 mlib_s32 dx_l, dx_r, dy_t, dy_b, wid_i, hgt_i;
101
102 MLIB_IMAGE_CHECK(dst);
103 MLIB_IMAGE_CHECK(src);
104 MLIB_IMAGE_TYPE_EQUAL(dst, src);
105 MLIB_IMAGE_CHAN_EQUAL(dst, src);
106
107 dst_wid = mlib_ImageGetWidth(dst);
108 dst_hgt = mlib_ImageGetHeight(dst);
109 src_wid = mlib_ImageGetWidth(src);
110 src_hgt = mlib_ImageGetHeight(src);
111
112 /* X clipping */
113 dx = src_wid - dst_wid;
114
115 if (dx > 0) {
116 dxs = (dx + 1) >> 1;
117 dxd = 0;
118 } else {
119 dxs = 0;
120 dxd = (-dx) >> 1;
121 }
122
123 dx_l = kw1 - dxs;
124 dx_r = kw2 + dxs - dx;
125
126 if (dx_l < 0) dx_l = 0;
127 if (dx_r < 0) dx_r = 0;
128 if (dx_r > kw2) dx_r = kw2;
129
130 /* Y clipping */
131 dy = src_hgt - dst_hgt;
132
133 if (dy > 0) {
134 dys = (dy + 1) >> 1;
135 dyd = 0;
136 } else {
137 dys = 0;
138 dyd = (-dy) >> 1;
139 }
140
141 dy_t = kh1 - dys;
142 dy_b = kh2 + dys - dy;
143
144 if (dy_t < 0) dy_t = 0;
145 if (dy_b < 0) dy_b = 0;
146 if (dy_b > kh2) dy_b = kh2;
147
148 /* image sizes */
149 wid_e = (src_wid < dst_wid) ? src_wid : dst_wid;
150 hgt_e = (src_hgt < dst_hgt) ? src_hgt : dst_hgt;
151 wid_i = wid_e + (kw1 - dx_l) + (kw2 - dx_r);
152 hgt_i = hgt_e + (kh1 - dy_t) + (kh2 - dy_b);
153
154 mlib_ImageSetSubimage(dst_i, dst, dxd - (kw1 - dx_l), dyd - (kh1 - dy_t), wid_i, hgt_i);
155 mlib_ImageSetSubimage(src_i, src, dxs - (kw1 - dx_l), dys - (kh1 - dy_t), wid_i, hgt_i);
156
157 if (dst_e != NULL && src_e != NULL) { /* images for edge processing */
158 mlib_ImageSetSubimage(dst_e, dst, dxd, dyd, wid_e, hgt_e);
159 mlib_ImageSetSubimage(src_e, src, dxs, dys, wid_e, hgt_e);
160 }
161
162 if (edg_sizes != NULL) { /* save edges */
163 edg_sizes[0] = dx_l;
164 edg_sizes[1] = dx_r;
165 edg_sizes[2] = dy_t;
166 edg_sizes[3] = dy_b;
167 }
168
169 return MLIB_SUCCESS;
170}
171
172/***************************************************************/
173mlib_status mlib_ImageClipping(mlib_image *dst_i,
174 mlib_image *src_i,
175 mlib_image *dst_e,
176 mlib_image *src_e,
177 mlib_s32 *edg_sizes,
178 const mlib_image *dst,
179 const mlib_image *src,
180 mlib_s32 ker_size)
181{
182 mlib_s32 kw1 = (ker_size - 1)/2;
183 return mlib_ImageClippingMxN(dst_i, src_i, dst_e, src_e, edg_sizes,
184 dst, src, ker_size, ker_size, kw1, kw1);
185}
186
187/***************************************************************/
188