mlib_status __mlib_ImageConv3x3( mlib_image *dst, const mlib_image *src, const mlib_s32 *kernel, mlib_s32 scale, mlib_s32 cmask, mlib_edge edge) { mlib_s32 ksize = 3, ksize2 = ksize / 2; mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1]; mlib_s32 edg_sizes[8]; mlib_type type; mlib_s32 nchan, dx_l, dx_r, dy_t, dy_b; mlib_s32 zero[4] = { 0, 0, 0, 0 }; mlib_status ret; ret = mlib_ImageClipping(dst_i, src_i, dst_e, src_e, edg_sizes, (void *)dst, (void *)src, ksize); if (ret != MLIB_SUCCESS) return (ret); if (kernel == NULL) return (MLIB_FAILURE); type = mlib_ImageGetType(dst); nchan = mlib_ImageGetChannels(dst); if (nchan == 1) cmask = 1; if ((cmask & ((1 << nchan) - 1)) == 0) return (MLIB_SUCCESS); dx_l = edg_sizes[0]; dx_r = edg_sizes[1]; dy_t = edg_sizes[2]; dy_b = edg_sizes[3]; if (dx_l + dx_r + dy_t + dy_b == 0) edge = MLIB_EDGE_DST_NO_WRITE; if (edge != MLIB_EDGE_SRC_EXTEND) { if (mlib_ImageGetWidth(src_i) >= ksize && mlib_ImageGetHeight(src_i) >= ksize) switch (type) { case MLIB_BIT: if (scale < 0) return (MLIB_FAILURE); mlib_conv3x3nw_bit(dst_i, src_i, (void *)kernel, scale, cmask); break; case MLIB_BYTE: if (scale < 16 || scale > 31) return (MLIB_FAILURE); mlib_s_conv3x3nw_u8(dst_i, src_i, (void *)kernel, scale, cmask); break; case MLIB_SHORT: if (scale < 17 || scale > 32) return (MLIB_FAILURE); mlib_s_conv3x3nw_s16(dst_i, src_i, (void *)kernel, scale, cmask); break; case MLIB_USHORT: if (scale < 17 || scale > 32) return (MLIB_FAILURE); mlib_s_conv3x3nw_u16(dst_i, src_i, (void *)kernel, scale, cmask); break; case MLIB_INT: if (scale < 0) return (MLIB_FAILURE); mlib_conv3x3nw_s32(dst_i, src_i, (void *)kernel, scale, cmask); break; default: return (MLIB_FAILURE); } switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: mlib_ImageConvClearEdge(dst_e, dx_l, dx_r, dy_t, dy_b, zero, cmask); break; case MLIB_EDGE_DST_COPY_SRC: mlib_ImageConvCopyEdge(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, cmask); break; } } else { /* MLIB_EDGE_SRC_EXTEND */ /* adjust src_e image */ mlib_ImageSetSubimage(src_e, src_e, dx_l - ksize2, dy_t - ksize2, mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e)); switch (type) { case MLIB_BIT: if (scale < 0) return (MLIB_FAILURE); mlib_conv3x3ext_bit(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask); break; case MLIB_BYTE: if (scale < 16 || scale > 31) return (MLIB_FAILURE); mlib_s_conv3x3ext_u8(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask); break; case MLIB_SHORT: if (scale < 17 || scale > 32) return (MLIB_FAILURE); mlib_s_conv3x3ext_s16(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask); break; case MLIB_USHORT: if (scale < 17 || scale > 32) return (MLIB_FAILURE); mlib_s_conv3x3ext_u16(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask); break; case MLIB_INT: if (scale < 0) return (MLIB_FAILURE); mlib_conv3x3ext_s32(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, (void *)kernel, scale, cmask); break; default: return (MLIB_FAILURE); } } return (MLIB_SUCCESS); }
mlib_status __mlib_ImageConvMxNIndex( mlib_image *dst, const mlib_image *src, const mlib_s32 *kernel, mlib_s32 m, mlib_s32 n, mlib_s32 dm, mlib_s32 dn, mlib_s32 scale, mlib_edge edge, const void *colormap) { mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1]; mlib_type img_type, lut_type; mlib_s32 offset, func_index; mlib_s32 dx_l, dx_r, dy_t, dy_b; mlib_s32 edg_sizes[8]; mlib_status ret; MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_CHECK(src); MLIB_IMAGE_TYPE_EQUAL(dst, src); MLIB_IMAGE_HAVE_CHAN(src, 1); MLIB_IMAGE_HAVE_CHAN(dst, 1); if (colormap == NULL || kernel == NULL) return (MLIB_FAILURE); img_type = mlib_ImageGetType(src); lut_type = mlib_ImageGetLutType(colormap); offset = (mlib_s32)mlib_ImageGetLutOffset(colormap); if (mlib_ImageGetWidth(src) < m || mlib_ImageGetHeight(src) < n) return (MLIB_FAILURE); if (((lut_type == MLIB_BYTE) && (scale < 16 || scale > 31)) || ((lut_type == MLIB_SHORT) && (scale < 17 || scale > 32))) return (MLIB_FAILURE); if (n < MIN_KRNL_HGT || m < MIN_KRNL_WID || dm < 0 || dm > m - 1 || dn < 0 || dn > n - 1) return (MLIB_FAILURE); ret = mlib_ImageClippingMxN(dst_i, src_i, dst_e, src_e, edg_sizes, dst, src, m, n, dm, dn); if (ret != MLIB_SUCCESS) return (ret); dx_l = edg_sizes[0]; dx_r = edg_sizes[1]; dy_t = edg_sizes[2]; dy_b = edg_sizes[3]; if (dx_l + dx_r + dy_t + dy_b == 0) edge = MLIB_EDGE_DST_NO_WRITE; func_index = 0; if (img_type == MLIB_SHORT) func_index += 1; if (lut_type == MLIB_SHORT) func_index += 2; if (edge != MLIB_EDGE_SRC_EXTEND) { if (mlib_ImageGetWidth(dst_i) >= m && mlib_ImageGetHeight(dst_i) >= n) { ret = func_convMxNIndex_nw[func_index](src_i, dst_i, m, n, dm, dn, kernel, scale, colormap); } switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: mlib_ImageConvClearEdge(dst_e, dx_l, dx_r, dy_t, dy_b, &offset, 1); break; case MLIB_EDGE_DST_COPY_SRC: mlib_ImageConvCopyEdge(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, 1); break; default: ret = MLIB_SUCCESS; break; } } else if (mlib_ImageGetWidth(dst_e) > 0 && mlib_ImageGetHeight(dst_e) > 0) { /* adjust src_e image */ mlib_ImageSetSubimage(src_e, src_e, dx_l - dm, dy_t - dn, mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e)); ret = func_convMxNIndex_ext[func_index](src_e, dst_e, m, n, dx_l, dx_r, dy_t, dy_b, kernel, scale, colormap); } return (ret); }
mlib_status __mlib_ImageConv4x4_Fp( mlib_image *dst, const mlib_image *src, const mlib_d64 *kernel, mlib_s32 cmask, mlib_edge edge) { mlib_s32 ksize = 4, ksize2 = (ksize - 1) / 2; mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1]; mlib_s32 edg_sizes[8]; mlib_type type; mlib_s32 nchan, dx_l, dx_r, dy_t, dy_b; mlib_d64 zero[4] = { 0, 0, 0, 0 }; mlib_status ret; ret = mlib_ImageClipping(dst_i, src_i, dst_e, src_e, edg_sizes, dst, src, ksize); if (ret != MLIB_SUCCESS) return (ret); if (kernel == NULL) return (MLIB_FAILURE); type = mlib_ImageGetType(dst); nchan = mlib_ImageGetChannels(dst); if (nchan == 1) cmask = 1; if ((cmask & ((1 << nchan) - 1)) == 0) return (MLIB_SUCCESS); dx_l = edg_sizes[0]; dx_r = edg_sizes[1]; dy_t = edg_sizes[2]; dy_b = edg_sizes[3]; if (dx_l + dx_r + dy_t + dy_b == 0) edge = MLIB_EDGE_DST_NO_WRITE; if (edge != MLIB_EDGE_SRC_EXTEND) { if (mlib_ImageGetWidth(src_i) >= ksize && mlib_ImageGetHeight(src_i) >= ksize) switch (type) { case MLIB_FLOAT: mlib_conv4x4nw_f32(dst_i, src_i, kernel, cmask); break; case MLIB_DOUBLE: mlib_conv4x4nw_d64(dst_i, src_i, kernel, cmask); break; default: return (MLIB_FAILURE); } switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: mlib_ImageConvClearEdge_Fp(dst_e, dx_l, dx_r, dy_t, dy_b, zero, cmask); break; case MLIB_EDGE_DST_COPY_SRC: mlib_ImageConvCopyEdge_Fp(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, cmask); break; default: return (MLIB_SUCCESS); } } else { /* MLIB_EDGE_SRC_EXTEND */ /* adjust src_e image */ mlib_ImageSetSubimage(src_e, src_e, dx_l - ksize2, dy_t - ksize2, mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e)); switch (type) { case MLIB_FLOAT: mlib_conv4x4ext_f32(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, kernel, cmask); break; case MLIB_DOUBLE: mlib_conv4x4ext_d64(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, kernel, cmask); break; default: return (MLIB_FAILURE); } } return (MLIB_SUCCESS); }
mlib_status mlib_ImageConvMxN_f(mlib_image *dst, const mlib_image *src, const void *kernel, mlib_s32 m, mlib_s32 n, mlib_s32 dm, mlib_s32 dn, mlib_s32 scale, mlib_s32 cmask, mlib_edge edge) { mlib_image dst_i[1], src_i[1], dst_e[1], src_e[1]; mlib_type type; mlib_s32 nchan, dx_l, dx_r, dy_t, dy_b; mlib_s32 edg_sizes[8]; mlib_status ret; if (m < 1 || n < 1 || dm < 0 || dm > m - 1 || dn < 0 || dn > n - 1) return MLIB_FAILURE; if (kernel == NULL) return MLIB_NULLPOINTER; ret = mlib_ImageClippingMxN(dst_i, src_i, dst_e, src_e, edg_sizes, dst, src, m, n, dm, dn); if (ret != MLIB_SUCCESS) return ret; nchan = mlib_ImageGetChannels(dst); type = mlib_ImageGetType(dst); if (nchan == 1) cmask = 1; if ((cmask & ((1 << nchan) - 1)) == 0) return MLIB_SUCCESS; dx_l = edg_sizes[0]; dx_r = edg_sizes[1]; dy_t = edg_sizes[2]; dy_b = edg_sizes[3]; if (dx_l + dx_r + dy_t + dy_b == 0) edge = MLIB_EDGE_DST_NO_WRITE; if (edge != MLIB_EDGE_SRC_EXTEND) { if (mlib_ImageGetWidth(dst_i) >= m && mlib_ImageGetHeight(dst_i) >= n) { switch (type) { case MLIB_BYTE: ret = mlib_convMxNnw_u8(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); break; case MLIB_SHORT: #ifdef __sparc ret = mlib_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); #else if (mlib_ImageConvVersion(m, n, scale, type) == 0) ret = mlib_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); else ret = mlib_i_convMxNnw_s16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); #endif /* __sparc */ break; case MLIB_USHORT: #ifdef __sparc ret = mlib_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); #else if (mlib_ImageConvVersion(m, n, scale, type) == 0) ret = mlib_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); else ret = mlib_i_convMxNnw_u16(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); #endif /* __sparc */ break; case MLIB_INT: ret = mlib_convMxNnw_s32(dst_i, src_i, kernel, m, n, dm, dn, scale, cmask); break; case MLIB_FLOAT: ret = mlib_convMxNnw_f32(dst_i, src_i, kernel, m, n, dm, dn, cmask); break; case MLIB_DOUBLE: ret = mlib_convMxNnw_d64(dst_i, src_i, kernel, m, n, dm, dn, cmask); break; } } switch (edge) { case MLIB_EDGE_DST_FILL_ZERO: mlib_ImageConvZeroEdge(dst_e, dx_l, dx_r, dy_t, dy_b, cmask); break; case MLIB_EDGE_DST_COPY_SRC: mlib_ImageConvCopyEdge(dst_e, src_e, dx_l, dx_r, dy_t, dy_b, cmask); break; } } else { /* MLIB_EDGE_SRC_EXTEND */ /* adjust src_e image */ mlib_ImageSetSubimage(src_e, src_e, dx_l - dm, dy_t - dn, mlib_ImageGetWidth(src_e), mlib_ImageGetHeight(src_e)); switch (type) { case MLIB_BYTE: ret = mlib_convMxNext_u8(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); break; case MLIB_SHORT: #ifdef __sparc ret = mlib_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); #else if (mlib_ImageConvVersion(m, n, scale, type) == 0) ret = mlib_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); else ret = mlib_i_convMxNext_s16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); #endif /* __sparc */ break; case MLIB_USHORT: #ifdef __sparc ret = mlib_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); #else if (mlib_ImageConvVersion(m, n, scale, type) == 0) ret = mlib_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); else ret = mlib_i_convMxNext_u16(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); #endif /* __sparc */ break; case MLIB_INT: ret = mlib_convMxNext_s32(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, scale, cmask); break; case MLIB_FLOAT: mlib_convMxNext_f32(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, cmask); break; case MLIB_DOUBLE: mlib_convMxNext_d64(dst_e, src_e, kernel, m, n, dx_l, dx_r, dy_t, dy_b, cmask); break; } } return ret; }