Path: blob/master/src/java.desktop/share/native/libmlib_image/mlib_ImageConvMxN.c
41149 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/242526/*27* FUNCTION28* mlib_ImageConvMxN - image convolution with edge condition29*30* SYNOPSIS31* mlib_status mlib_ImageConvMxN(mlib_image *dst,32* const mlib_image *src,33* const mlib_s32 *kernel,34* mlib_s32 m,35* mlib_s32 n,36* mlib_s32 dm,37* mlib_s32 dn,38* mlib_s32 scale,39* mlib_s32 cmask,40* mlib_edge edge)41*42* ARGUMENTS43* dst Pointer to destination image.44* src Pointer to source image.45* m Kernel width (m must be not less than 1).46* n Kernel height (n must be not less than 1).47* dm, dn Position of key element in convolution kernel.48* kernel Pointer to convolution kernel.49* scale The scaling factor to convert the input integer50* coefficients into floating-point coefficients:51* floating-point coefficient = integer coefficient * 2^(-scale)52* cmask Channel mask to indicate the channels to be convolved.53* Each bit of which represents a channel in the image. The54* channels corresponded to 1 bits are those to be processed.55* edge Type of edge condition.56*57* DESCRIPTION58* 2-D convolution, MxN kernel.59*60* The center of the source image is mapped to the center of the61* destination image.62* The unselected channels are not overwritten. If both src and dst have63* just one channel, cmask is ignored.64*65* The edge condition can be one of the following:66* MLIB_EDGE_DST_NO_WRITE (default)67* MLIB_EDGE_DST_FILL_ZERO68* MLIB_EDGE_DST_COPY_SRC69* MLIB_EDGE_SRC_EXTEND70*71* RESTRICTION72* The src and the dst must be the same type and have same number73* of channels (1, 2, 3, or 4). They can be in MLIB_BIT, MLIB_BYTE,74* MLIB_SHORT, MLIB_USHORT or MLIB_INT data type.75* m >= 1, n >= 1,76* 0 <= dm < m, 0 <= dn < n.77* For data type MLIB_BYTE: 16 <= scale <= 31 (to be compatible with VIS version)78* For data type MLIB_SHORT: 17 <= scale <= 32 (to be compatible with VIS version)79* For data type MLIB_USHORT: 17 <= scale <= 32 (to be compatible with VIS version)80* For data type MLIB_INT: scale >= 081*/8283#include "mlib_image.h"84#include "mlib_ImageCheck.h"85#include "mlib_ImageConv.h"86#include "mlib_ImageCreate.h"87#include "mlib_c_ImageConv.h"88#include "mlib_ImageClipping.h"89#include "mlib_ImageConvEdge.h"9091/***************************************************************/92JNIEXPORT93mlib_status mlib_ImageConvMxN(mlib_image *dst,94const mlib_image *src,95const mlib_s32 *kernel,96mlib_s32 m,97mlib_s32 n,98mlib_s32 dm,99mlib_s32 dn,100mlib_s32 scale,101mlib_s32 cmask,102mlib_edge edge)103{104MLIB_IMAGE_CHECK(dst);105106switch (mlib_ImageGetType(dst)) {107case MLIB_BYTE:108109if (scale < 16 || scale > 31)110return MLIB_FAILURE;111break;112case MLIB_SHORT:113case MLIB_USHORT:114115if (scale < 17 || scale > 32)116return MLIB_FAILURE;117break;118case MLIB_INT:119120if (scale < 0)121return MLIB_FAILURE;122break;123default:124return MLIB_FAILURE;125}126127return mlib_ImageConvMxN_f(dst, src, kernel, m, n, dm, dn, scale, cmask, edge);128}129130/***************************************************************/131mlib_status mlib_ImageConvMxN_f(mlib_image *dst,132const mlib_image *src,133const void *kernel,134mlib_s32 m,135mlib_s32 n,136mlib_s32 dm,137mlib_s32 dn,138mlib_s32 scale,139mlib_s32 cmask,140mlib_edge edge)141{142mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1];143mlib_type type;144mlib_s32 nchan, dx_l, dx_r, dy_t, dy_b;145mlib_s32 edg_sizes[8];146mlib_status ret;147148if (m < 1 || n < 1 || dm < 0 || dm > m - 1 || dn < 0 || dn > n - 1)149return MLIB_FAILURE;150151if (kernel == NULL)152return MLIB_NULLPOINTER;153154ret =155mlib_ImageClippingMxN(dst_i, src_i, dst_e, src_e, edg_sizes, dst, src, m, n, dm, dn);156157if (ret != MLIB_SUCCESS)158return ret;159160nchan = mlib_ImageGetChannels(dst);161type = mlib_ImageGetType(dst);162163if (nchan == 1)164cmask = 1;165166if ((cmask & ((1 << nchan) - 1)) == 0)167return MLIB_SUCCESS;168169dx_l = edg_sizes[0];170dx_r = edg_sizes[1];171dy_t = edg_sizes[2];172dy_b = edg_sizes[3];173174if (dx_l + dx_r + dy_t + dy_b == 0)175edge = MLIB_EDGE_DST_NO_WRITE;176177if (edge != MLIB_EDGE_SRC_EXTEND) {178if (mlib_ImageGetWidth(dst_i) >= m && mlib_ImageGetHeight(dst_i) >= n) {179switch (type) {180case MLIB_BYTE:181ret = mlib_convMxNnw_u8(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);182break;183case MLIB_SHORT:184if (mlib_ImageConvVersion(m, n, scale, type) == 0)185ret = mlib_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);186else187ret = mlib_i_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);188break;189case MLIB_USHORT:190if (mlib_ImageConvVersion(m, n, scale, type) == 0)191ret = mlib_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);192else193ret = mlib_i_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);194break;195case MLIB_INT:196ret = mlib_convMxNnw_s32(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask);197break;198case MLIB_FLOAT:199ret = mlib_convMxNnw_f32(dst_i, src_i, kernel, m, n, dm, dn, cmask);200break;201case MLIB_DOUBLE:202ret = mlib_convMxNnw_d64(dst_i, src_i, kernel, m, n, dm, dn, cmask);203break;204205default:206/* For some reasons, there is no convolution routine for type MLIB_BIT.207* For now, we silently ignore it (because this image type is not used by java),208* but probably we have to report an error.209*/210break;211}212}213214switch (edge) {215case MLIB_EDGE_DST_FILL_ZERO:216mlib_ImageConvZeroEdge(dst_e, dx_l, dx_r, dy_t, dy_b, cmask);217break;218case MLIB_EDGE_DST_COPY_SRC:219mlib_ImageConvCopyEdge(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, cmask);220break;221default:222/* Other edge conditions do not need additional handling.223* Note also that they are not exposed in public Java API224*/225break;226}227}228else { /* MLIB_EDGE_SRC_EXTEND */229/* adjust src_e image */230mlib_ImageSetSubimage(src_e, src_e, dx_l - dm, dy_t - dn,231mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e));232233switch (type) {234case MLIB_BYTE:235ret =236mlib_convMxNext_u8(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,237cmask);238break;239case MLIB_SHORT:240if (mlib_ImageConvVersion(m, n, scale, type) == 0)241ret =242mlib_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,243cmask);244else245ret =246mlib_i_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b,247scale, cmask);248break;249case MLIB_USHORT:250if (mlib_ImageConvVersion(m, n, scale, type) == 0)251ret =252mlib_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,253cmask);254else255ret =256mlib_i_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b,257scale, cmask);258break;259case MLIB_INT:260ret =261mlib_convMxNext_s32(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale,262cmask);263break;264case MLIB_FLOAT:265mlib_convMxNext_f32(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, cmask);266break;267case MLIB_DOUBLE:268mlib_convMxNext_d64(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, cmask);269break;270default:271/* For some reasons, there is no convolution routine for type MLIB_BIT.272* For now, we silently ignore it (because this image type is not used by java),273* but probably we have to report an error.274*/275break;276}277}278279return ret;280}281282/***************************************************************/283284285