--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_ImageAffine.c Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * FUNCTION
+ * mlib_ImageAffine - image affine transformation with edge condition
+ *
+ * SYNOPSIS
+ * mlib_status mlib_ImageAffine(mlib_image *dst,
+ * const mlib_image *src,
+ * const mlib_d64 *mtx,
+ * mlib_filter filter,
+ * mlib_edge edge)
+ *
+ * ARGUMENTS
+ * dst Pointer to destination image
+ * src Pointer to source image
+ * mtx Transformation matrix, where
+ * mtx[0] holds a; mtx[1] holds b;
+ * mtx[2] holds tx; mtx[3] holds c;
+ * mtx[4] holds d; mtx[5] holds ty.
+ * filter Type of resampling filter.
+ * edge Type of edge condition.
+ *
+ * DESCRIPTION
+ * xd = a*xs + b*ys + tx
+ * yd = c*xs + d*ys + ty
+ *
+ * The upper-left corner pixel of an image is located at (0.5, 0.5).
+ *
+ * The resampling filter can be one of the following:
+ * MLIB_NEAREST
+ * MLIB_BILINEAR
+ * MLIB_BICUBIC
+ * MLIB_BICUBIC2
+ *
+ * The edge condition can be one of the following:
+ * MLIB_EDGE_DST_NO_WRITE (default)
+ * MLIB_EDGE_DST_FILL_ZERO
+ * MLIB_EDGE_OP_NEAREST
+ * MLIB_EDGE_SRC_EXTEND
+ * MLIB_EDGE_SRC_PADDED
+ *
+ * RESTRICTION
+ * src and dst must be the same type and the same number of channels.
+ * They can have 1, 2, 3 or 4 channels. They can be in MLIB_BIT, MLIB_BYTE,
+ * MLIB_SHORT, MLIB_USHORT or MLIB_INT data type.
+ *
+ * src image can not have width or height larger than 32767.
+ */
+
+#include "mlib_ImageCheck.h"
+#include "mlib_ImageColormap.h"
+#include "mlib_ImageAffine.h"
+
+
+/***************************************************************/
+#define BUFF_SIZE 600
+
+/***************************************************************/
+const type_affine_fun mlib_AffineFunArr_nn[] = {
+ mlib_ImageAffine_u8_1ch_nn, mlib_ImageAffine_u8_2ch_nn,
+ mlib_ImageAffine_u8_3ch_nn, mlib_ImageAffine_u8_4ch_nn,
+ mlib_ImageAffine_s16_1ch_nn, mlib_ImageAffine_s16_2ch_nn,
+ mlib_ImageAffine_s16_3ch_nn, mlib_ImageAffine_s16_4ch_nn,
+ mlib_ImageAffine_s32_1ch_nn, mlib_ImageAffine_s32_2ch_nn,
+ mlib_ImageAffine_s32_3ch_nn, mlib_ImageAffine_s32_4ch_nn,
+ mlib_ImageAffine_d64_1ch_nn, mlib_ImageAffine_d64_2ch_nn,
+ mlib_ImageAffine_d64_3ch_nn, mlib_ImageAffine_d64_4ch_nn,
+};
+
+/***************************************************************/
+const type_affine_fun mlib_AffineFunArr_bl[] = {
+ mlib_ImageAffine_u8_1ch_bl, mlib_ImageAffine_u8_2ch_bl,
+ mlib_ImageAffine_u8_3ch_bl, mlib_ImageAffine_u8_4ch_bl,
+ mlib_ImageAffine_s16_1ch_bl, mlib_ImageAffine_s16_2ch_bl,
+ mlib_ImageAffine_s16_3ch_bl, mlib_ImageAffine_s16_4ch_bl,
+ mlib_ImageAffine_s32_1ch_bl, mlib_ImageAffine_s32_2ch_bl,
+ mlib_ImageAffine_s32_3ch_bl, mlib_ImageAffine_s32_4ch_bl,
+ mlib_ImageAffine_u16_1ch_bl, mlib_ImageAffine_u16_2ch_bl,
+ mlib_ImageAffine_u16_3ch_bl, mlib_ImageAffine_u16_4ch_bl,
+ mlib_ImageAffine_f32_1ch_bl, mlib_ImageAffine_f32_2ch_bl,
+ mlib_ImageAffine_f32_3ch_bl, mlib_ImageAffine_f32_4ch_bl,
+ mlib_ImageAffine_d64_1ch_bl, mlib_ImageAffine_d64_2ch_bl,
+ mlib_ImageAffine_d64_3ch_bl, mlib_ImageAffine_d64_4ch_bl
+};
+
+/***************************************************************/
+const type_affine_fun mlib_AffineFunArr_bc[] = {
+ mlib_ImageAffine_u8_1ch_bc, mlib_ImageAffine_u8_2ch_bc,
+ mlib_ImageAffine_u8_3ch_bc, mlib_ImageAffine_u8_4ch_bc,
+ mlib_ImageAffine_s16_1ch_bc, mlib_ImageAffine_s16_2ch_bc,
+ mlib_ImageAffine_s16_3ch_bc, mlib_ImageAffine_s16_4ch_bc,
+ mlib_ImageAffine_s32_1ch_bc, mlib_ImageAffine_s32_2ch_bc,
+ mlib_ImageAffine_s32_3ch_bc, mlib_ImageAffine_s32_4ch_bc,
+ mlib_ImageAffine_u16_1ch_bc, mlib_ImageAffine_u16_2ch_bc,
+ mlib_ImageAffine_u16_3ch_bc, mlib_ImageAffine_u16_4ch_bc,
+ mlib_ImageAffine_f32_1ch_bc, mlib_ImageAffine_f32_2ch_bc,
+ mlib_ImageAffine_f32_3ch_bc, mlib_ImageAffine_f32_4ch_bc,
+ mlib_ImageAffine_d64_1ch_bc, mlib_ImageAffine_d64_2ch_bc,
+ mlib_ImageAffine_d64_3ch_bc, mlib_ImageAffine_d64_4ch_bc
+};
+
+/***************************************************************/
+const type_affine_i_fun mlib_AffineFunArr_bc_i[] = {
+ mlib_ImageAffineIndex_U8_U8_3CH_BC,
+ mlib_ImageAffineIndex_U8_U8_4CH_BC,
+ mlib_ImageAffineIndex_S16_U8_3CH_BC,
+ mlib_ImageAffineIndex_S16_U8_4CH_BC,
+ mlib_ImageAffineIndex_U8_S16_3CH_BC,
+ mlib_ImageAffineIndex_U8_S16_4CH_BC,
+ mlib_ImageAffineIndex_S16_S16_3CH_BC,
+ mlib_ImageAffineIndex_S16_S16_4CH_BC
+};
+
+/***************************************************************/
+#ifdef i386 /* do not perform the coping by mlib_d64 data type for x86 */
+#define MAX_T_IND 2
+#else
+#define MAX_T_IND 3
+#endif /* i386 ( do not perform the coping by mlib_d64 data type for x86 ) */
+
+/***************************************************************/
+mlib_status mlib_ImageAffine_alltypes(mlib_image *dst,
+ const mlib_image *src,
+ const mlib_d64 *mtx,
+ mlib_filter filter,
+ mlib_edge edge,
+ const void *colormap)
+{
+ mlib_affine_param param[1];
+ mlib_status res;
+ mlib_type type;
+ mlib_s32 nchan, t_ind, kw, kw1;
+ mlib_addr align;
+ mlib_d64 buff_lcl[BUFF_SIZE / 8];
+ mlib_u8 **lineAddr = NULL;
+
+ /* check for obvious errors */
+ MLIB_IMAGE_TYPE_EQUAL(src, dst);
+ MLIB_IMAGE_CHAN_EQUAL(src, dst);
+
+ type = mlib_ImageGetType(dst);
+ nchan = mlib_ImageGetChannels(dst);
+
+ switch (filter) {
+ case MLIB_NEAREST:
+ kw = 1;
+ kw1 = 0;
+ break;
+
+ case MLIB_BILINEAR:
+ kw = 2;
+ kw1 = 0;
+ break;
+
+ case MLIB_BICUBIC:
+ case MLIB_BICUBIC2:
+ kw = 4;
+ kw1 = 1;
+ break;
+
+ default:
+ return MLIB_FAILURE;
+ }
+
+ STORE_PARAM(param, lineAddr);
+ STORE_PARAM(param, filter);
+
+ res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,
+ kw, kw, kw1, kw1, edge, mtx, MLIB_SHIFT, MLIB_SHIFT);
+
+ if (res != MLIB_SUCCESS)
+ return res;
+
+ lineAddr = param->lineAddr;
+
+ if (type == MLIB_BYTE)
+ t_ind = 0;
+ else if (type == MLIB_SHORT)
+ t_ind = 1;
+ else if (type == MLIB_INT)
+ t_ind = 2;
+ else if (type == MLIB_USHORT)
+ t_ind = 3;
+ else if (type == MLIB_FLOAT)
+ t_ind = 4;
+ else if (type == MLIB_DOUBLE)
+ t_ind = 5;
+
+ if (colormap != NULL && filter != MLIB_NEAREST) {
+ if (t_ind != 0 && t_ind != 1)
+ return MLIB_FAILURE;
+
+ if (mlib_ImageGetLutType(colormap) == MLIB_SHORT)
+ t_ind += 2;
+ t_ind = 2 * t_ind;
+
+ if (mlib_ImageGetLutChannels(colormap) == 4)
+ t_ind++;
+ }
+
+ if (type == MLIB_BIT) {
+ mlib_s32 s_bitoff = mlib_ImageGetBitOffset(src);
+ mlib_s32 d_bitoff = mlib_ImageGetBitOffset(dst);
+
+ if (nchan != 1 || filter != MLIB_NEAREST)
+ return MLIB_FAILURE;
+ mlib_ImageAffine_bit_1ch_nn(param, s_bitoff, d_bitoff);
+ }
+ else {
+ switch (filter) {
+ case MLIB_NEAREST:
+
+ if (t_ind >= 3)
+ t_ind -= 2; /* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */
+
+ /* two channels as one channel of next type */
+ align = (mlib_addr) (param->dstData) | (mlib_addr) lineAddr[0];
+ align |= param->dstYStride | param->srcYStride;
+ while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < MAX_T_IND) {
+ nchan >>= 1;
+ t_ind++;
+ }
+
+ res = mlib_AffineFunArr_nn[4 * t_ind + (nchan - 1)] (param);
+ break;
+
+ case MLIB_BILINEAR:
+
+ if (colormap != NULL) {
+ res = mlib_AffineFunArr_bl_i[t_ind] (param, colormap);
+ }
+ else {
+ res = mlib_AffineFunArr_bl[4 * t_ind + (nchan - 1)] (param);
+ }
+
+ break;
+
+ case MLIB_BICUBIC:
+ case MLIB_BICUBIC2:
+
+ if (colormap != NULL) {
+ res = mlib_AffineFunArr_bc_i[t_ind] (param, colormap);
+ }
+ else {
+ res = mlib_AffineFunArr_bc[4 * t_ind + (nchan - 1)] (param);
+ }
+
+ break;
+ }
+
+ if (res != MLIB_SUCCESS) {
+ if (param->buff_malloc != NULL)
+ mlib_free(param->buff_malloc);
+ return res;
+ }
+ }
+
+ if (edge == MLIB_EDGE_SRC_PADDED)
+ edge = MLIB_EDGE_DST_NO_WRITE;
+
+ if (filter != MLIB_NEAREST && edge != MLIB_EDGE_DST_NO_WRITE) {
+ mlib_affine_param param_e[1];
+ mlib_d64 buff_lcl1[BUFF_SIZE / 8];
+
+ STORE_PARAM(param_e, lineAddr);
+ STORE_PARAM(param_e, filter);
+
+ res = mlib_AffineEdges(param_e, dst, src, buff_lcl1, BUFF_SIZE,
+ kw, kw, kw1, kw1, -1, mtx, MLIB_SHIFT, MLIB_SHIFT);
+
+ if (res != MLIB_SUCCESS) {
+ if (param->buff_malloc != NULL)
+ mlib_free(param->buff_malloc);
+ return res;
+ }
+
+ switch (edge) {
+ case MLIB_EDGE_DST_FILL_ZERO:
+ mlib_ImageAffineEdgeZero(param, param_e, colormap);
+ break;
+
+ case MLIB_EDGE_OP_NEAREST:
+ mlib_ImageAffineEdgeNearest(param, param_e);
+ break;
+
+ case MLIB_EDGE_SRC_EXTEND:
+
+ if (filter == MLIB_BILINEAR) {
+ res = mlib_ImageAffineEdgeExtend_BL(param, param_e, colormap);
+ }
+ else {
+ res = mlib_ImageAffineEdgeExtend_BC(param, param_e, colormap);
+ }
+
+ break;
+ }
+
+ if (param_e->buff_malloc != NULL)
+ mlib_free(param_e->buff_malloc);
+ }
+
+ if (param->buff_malloc != NULL)
+ mlib_free(param->buff_malloc);
+
+ return res;
+}
+
+/***************************************************************/
+mlib_status mlib_ImageAffine(mlib_image *dst,
+ const mlib_image *src,
+ const mlib_d64 *mtx,
+ mlib_filter filter,
+ mlib_edge edge)
+{
+ mlib_type type;
+
+ MLIB_IMAGE_CHECK(src);
+ MLIB_IMAGE_CHECK(dst);
+
+ type = mlib_ImageGetType(dst);
+
+ if (type != MLIB_BIT && type != MLIB_BYTE &&
+ type != MLIB_SHORT && type != MLIB_USHORT && type != MLIB_INT) {
+ return MLIB_FAILURE;
+ }
+
+ return mlib_ImageAffine_alltypes(dst, src, mtx, filter, edge, NULL);
+}
+
+/***************************************************************/