Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/awt/medialib/mlib_ImageAffine.c
38918 views
/*1* Copyright (c) 2003, 2011, 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_ImageAffine - image affine transformation with edge condition29*30* SYNOPSIS31* mlib_status mlib_ImageAffine(mlib_image *dst,32* const mlib_image *src,33* const mlib_d64 *mtx,34* mlib_filter filter,35* mlib_edge edge)36*37* ARGUMENTS38* dst Pointer to destination image39* src Pointer to source image40* mtx Transformation matrix, where41* mtx[0] holds a; mtx[1] holds b;42* mtx[2] holds tx; mtx[3] holds c;43* mtx[4] holds d; mtx[5] holds ty.44* filter Type of resampling filter.45* edge Type of edge condition.46*47* DESCRIPTION48* xd = a*xs + b*ys + tx49* yd = c*xs + d*ys + ty50*51* The upper-left corner pixel of an image is located at (0.5, 0.5).52*53* The resampling filter can be one of the following:54* MLIB_NEAREST55* MLIB_BILINEAR56* MLIB_BICUBIC57* MLIB_BICUBIC258*59* The edge condition can be one of the following:60* MLIB_EDGE_DST_NO_WRITE (default)61* MLIB_EDGE_DST_FILL_ZERO62* MLIB_EDGE_OP_NEAREST63* MLIB_EDGE_SRC_EXTEND64* MLIB_EDGE_SRC_PADDED65*66* RESTRICTION67* src and dst must be the same type and the same number of channels.68* They can have 1, 2, 3 or 4 channels. They can be in MLIB_BIT, MLIB_BYTE,69* MLIB_SHORT, MLIB_USHORT or MLIB_INT data type.70*71* src image can not have width or height larger than 32767.72*/7374#include "mlib_ImageCheck.h"75#include "mlib_ImageColormap.h"76#include "mlib_ImageAffine.h"777879/***************************************************************/80#define BUFF_SIZE 6008182/***************************************************************/83const type_affine_fun mlib_AffineFunArr_nn[] = {84mlib_ImageAffine_u8_1ch_nn, mlib_ImageAffine_u8_2ch_nn,85mlib_ImageAffine_u8_3ch_nn, mlib_ImageAffine_u8_4ch_nn,86mlib_ImageAffine_s16_1ch_nn, mlib_ImageAffine_s16_2ch_nn,87mlib_ImageAffine_s16_3ch_nn, mlib_ImageAffine_s16_4ch_nn,88mlib_ImageAffine_s32_1ch_nn, mlib_ImageAffine_s32_2ch_nn,89mlib_ImageAffine_s32_3ch_nn, mlib_ImageAffine_s32_4ch_nn,90mlib_ImageAffine_d64_1ch_nn, mlib_ImageAffine_d64_2ch_nn,91mlib_ImageAffine_d64_3ch_nn, mlib_ImageAffine_d64_4ch_nn,92};9394/***************************************************************/95const type_affine_fun mlib_AffineFunArr_bl[] = {96mlib_ImageAffine_u8_1ch_bl, mlib_ImageAffine_u8_2ch_bl,97mlib_ImageAffine_u8_3ch_bl, mlib_ImageAffine_u8_4ch_bl,98mlib_ImageAffine_s16_1ch_bl, mlib_ImageAffine_s16_2ch_bl,99mlib_ImageAffine_s16_3ch_bl, mlib_ImageAffine_s16_4ch_bl,100mlib_ImageAffine_s32_1ch_bl, mlib_ImageAffine_s32_2ch_bl,101mlib_ImageAffine_s32_3ch_bl, mlib_ImageAffine_s32_4ch_bl,102mlib_ImageAffine_u16_1ch_bl, mlib_ImageAffine_u16_2ch_bl,103mlib_ImageAffine_u16_3ch_bl, mlib_ImageAffine_u16_4ch_bl,104mlib_ImageAffine_f32_1ch_bl, mlib_ImageAffine_f32_2ch_bl,105mlib_ImageAffine_f32_3ch_bl, mlib_ImageAffine_f32_4ch_bl,106mlib_ImageAffine_d64_1ch_bl, mlib_ImageAffine_d64_2ch_bl,107mlib_ImageAffine_d64_3ch_bl, mlib_ImageAffine_d64_4ch_bl108};109110/***************************************************************/111const type_affine_fun mlib_AffineFunArr_bc[] = {112mlib_ImageAffine_u8_1ch_bc, mlib_ImageAffine_u8_2ch_bc,113mlib_ImageAffine_u8_3ch_bc, mlib_ImageAffine_u8_4ch_bc,114mlib_ImageAffine_s16_1ch_bc, mlib_ImageAffine_s16_2ch_bc,115mlib_ImageAffine_s16_3ch_bc, mlib_ImageAffine_s16_4ch_bc,116mlib_ImageAffine_s32_1ch_bc, mlib_ImageAffine_s32_2ch_bc,117mlib_ImageAffine_s32_3ch_bc, mlib_ImageAffine_s32_4ch_bc,118mlib_ImageAffine_u16_1ch_bc, mlib_ImageAffine_u16_2ch_bc,119mlib_ImageAffine_u16_3ch_bc, mlib_ImageAffine_u16_4ch_bc,120mlib_ImageAffine_f32_1ch_bc, mlib_ImageAffine_f32_2ch_bc,121mlib_ImageAffine_f32_3ch_bc, mlib_ImageAffine_f32_4ch_bc,122mlib_ImageAffine_d64_1ch_bc, mlib_ImageAffine_d64_2ch_bc,123mlib_ImageAffine_d64_3ch_bc, mlib_ImageAffine_d64_4ch_bc124};125126/***************************************************************/127const type_affine_i_fun mlib_AffineFunArr_bc_i[] = {128mlib_ImageAffineIndex_U8_U8_3CH_BC,129mlib_ImageAffineIndex_U8_U8_4CH_BC,130mlib_ImageAffineIndex_S16_U8_3CH_BC,131mlib_ImageAffineIndex_S16_U8_4CH_BC,132mlib_ImageAffineIndex_U8_S16_3CH_BC,133mlib_ImageAffineIndex_U8_S16_4CH_BC,134mlib_ImageAffineIndex_S16_S16_3CH_BC,135mlib_ImageAffineIndex_S16_S16_4CH_BC136};137138/***************************************************************/139#ifdef i386 /* do not perform the coping by mlib_d64 data type for x86 */140#define MAX_T_IND 2141#else142#define MAX_T_IND 3143#endif /* i386 ( do not perform the coping by mlib_d64 data type for x86 ) */144145/***************************************************************/146mlib_status mlib_ImageAffine_alltypes(mlib_image *dst,147const mlib_image *src,148const mlib_d64 *mtx,149mlib_filter filter,150mlib_edge edge,151const void *colormap)152{153mlib_affine_param param[1];154mlib_status res;155mlib_type type;156mlib_s32 nchan, t_ind, kw, kw1;157mlib_addr align;158mlib_d64 buff_lcl[BUFF_SIZE / 8];159mlib_u8 **lineAddr = NULL;160161/* check for obvious errors */162MLIB_IMAGE_TYPE_EQUAL(src, dst);163MLIB_IMAGE_CHAN_EQUAL(src, dst);164165type = mlib_ImageGetType(dst);166nchan = mlib_ImageGetChannels(dst);167168switch (filter) {169case MLIB_NEAREST:170kw = 1;171kw1 = 0;172break;173174case MLIB_BILINEAR:175kw = 2;176kw1 = 0;177break;178179case MLIB_BICUBIC:180case MLIB_BICUBIC2:181kw = 4;182kw1 = 1;183break;184185default:186return MLIB_FAILURE;187}188189STORE_PARAM(param, lineAddr);190STORE_PARAM(param, filter);191192res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,193kw, kw, kw1, kw1, edge, mtx, MLIB_SHIFT, MLIB_SHIFT);194195if (res != MLIB_SUCCESS)196return res;197198lineAddr = param->lineAddr;199200if (type == MLIB_BYTE)201t_ind = 0;202else if (type == MLIB_SHORT)203t_ind = 1;204else if (type == MLIB_INT)205t_ind = 2;206else if (type == MLIB_USHORT)207t_ind = 3;208else if (type == MLIB_FLOAT)209t_ind = 4;210else if (type == MLIB_DOUBLE)211t_ind = 5;212else213return MLIB_FAILURE; /* unknown image type */214215if (colormap != NULL && filter != MLIB_NEAREST) {216if (t_ind != 0 && t_ind != 1)217return MLIB_FAILURE;218219if (mlib_ImageGetLutType(colormap) == MLIB_SHORT)220t_ind += 2;221t_ind = 2 * t_ind;222223if (mlib_ImageGetLutChannels(colormap) == 4)224t_ind++;225}226227if (type == MLIB_BIT) {228mlib_s32 s_bitoff = mlib_ImageGetBitOffset(src);229mlib_s32 d_bitoff = mlib_ImageGetBitOffset(dst);230231if (nchan != 1 || filter != MLIB_NEAREST)232return MLIB_FAILURE;233mlib_ImageAffine_bit_1ch_nn(param, s_bitoff, d_bitoff);234}235else {236switch (filter) {237case MLIB_NEAREST:238239if (t_ind >= 3)240t_ind -= 2; /* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */241242/* two channels as one channel of next type */243align = (mlib_addr) (param->dstData) | (mlib_addr) lineAddr[0];244align |= param->dstYStride | param->srcYStride;245while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < MAX_T_IND) {246nchan >>= 1;247t_ind++;248}249250res = mlib_AffineFunArr_nn[4 * t_ind + (nchan - 1)] (param);251break;252253case MLIB_BILINEAR:254255if (colormap != NULL) {256res = mlib_AffineFunArr_bl_i[t_ind] (param, colormap);257}258else {259res = mlib_AffineFunArr_bl[4 * t_ind + (nchan - 1)] (param);260}261262break;263264case MLIB_BICUBIC:265case MLIB_BICUBIC2:266267if (colormap != NULL) {268res = mlib_AffineFunArr_bc_i[t_ind] (param, colormap);269}270else {271res = mlib_AffineFunArr_bc[4 * t_ind + (nchan - 1)] (param);272}273274break;275}276277if (res != MLIB_SUCCESS) {278if (param->buff_malloc != NULL)279mlib_free(param->buff_malloc);280return res;281}282}283284if (edge == MLIB_EDGE_SRC_PADDED)285edge = MLIB_EDGE_DST_NO_WRITE;286287if (filter != MLIB_NEAREST && edge != MLIB_EDGE_DST_NO_WRITE) {288mlib_affine_param param_e[1];289mlib_d64 buff_lcl1[BUFF_SIZE / 8];290291STORE_PARAM(param_e, lineAddr);292STORE_PARAM(param_e, filter);293294res = mlib_AffineEdges(param_e, dst, src, buff_lcl1, BUFF_SIZE,295kw, kw, kw1, kw1, -1, mtx, MLIB_SHIFT, MLIB_SHIFT);296297if (res != MLIB_SUCCESS) {298if (param->buff_malloc != NULL)299mlib_free(param->buff_malloc);300return res;301}302303switch (edge) {304case MLIB_EDGE_DST_FILL_ZERO:305mlib_ImageAffineEdgeZero(param, param_e, colormap);306break;307308case MLIB_EDGE_OP_NEAREST:309mlib_ImageAffineEdgeNearest(param, param_e);310break;311312case MLIB_EDGE_SRC_EXTEND:313314if (filter == MLIB_BILINEAR) {315res = mlib_ImageAffineEdgeExtend_BL(param, param_e, colormap);316}317else {318res = mlib_ImageAffineEdgeExtend_BC(param, param_e, colormap);319}320321break;322323default:324/* nothing to do for other edge types. */325break;326}327328if (param_e->buff_malloc != NULL)329mlib_free(param_e->buff_malloc);330}331332if (param->buff_malloc != NULL)333mlib_free(param->buff_malloc);334335return res;336}337338/***************************************************************/339mlib_status mlib_ImageAffine(mlib_image *dst,340const mlib_image *src,341const mlib_d64 *mtx,342mlib_filter filter,343mlib_edge edge)344{345mlib_type type;346347MLIB_IMAGE_CHECK(src);348MLIB_IMAGE_CHECK(dst);349350type = mlib_ImageGetType(dst);351352if (type != MLIB_BIT && type != MLIB_BYTE &&353type != MLIB_SHORT && type != MLIB_USHORT && type != MLIB_INT) {354return MLIB_FAILURE;355}356357return mlib_ImageAffine_alltypes(dst, src, mtx, filter, edge, NULL);358}359360/***************************************************************/361362363