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 /***************************************************************/
mlib_ImageClippingMxN(mlib_image * dst_i,mlib_image * src_i,mlib_image * dst_e,mlib_image * src_e,mlib_s32 * edg_sizes,const mlib_image * dst,const mlib_image * src,mlib_s32 kw,mlib_s32 kh,mlib_s32 kw1,mlib_s32 kh1)84 mlib_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 /***************************************************************/
mlib_ImageClipping(mlib_image * dst_i,mlib_image * src_i,mlib_image * dst_e,mlib_image * src_e,mlib_s32 * edg_sizes,const mlib_image * dst,const mlib_image * src,mlib_s32 ker_size)173 mlib_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