| /* |
| * Copyright (c) 1999, 2003, Oracle and/or its affiliates. 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. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| |
| |
| /* |
| * FUNCTIONS |
| * mlib_v_ImageCopy_a1 - 1-D, Aligned8, size 8x |
| * mlib_v_ImageCopy_a2 - 2-D, Aligned8, width 8x |
| * mlib_ImageCopy_na - BYTE, non-aligned |
| * mlib_ImageCopy_bit_al - BIT, aligned |
| * |
| * SYNOPSIS |
| * |
| * ARGUMENT |
| * sp pointer to source image data |
| * dp pointer to destination image data |
| * size size in 8-bytes, bytes, or SHORTs |
| * width image width in 8-bytes |
| * height image height in lines |
| * stride source image line stride in 8-bytes |
| * dstride destination image line stride in 8-bytes |
| * s_offset source image line bit offset |
| * d_offset destination image line bit offset |
| * |
| * DESCRIPTION |
| * Direct copy from one image to another -- VIS version low level |
| * functions. |
| * |
| * NOTE |
| * These functions are separated from mlib_v_ImageCopy.c for loop |
| * unrolling and structure clarity. |
| */ |
| |
| #include "vis_proto.h" |
| #include "mlib_image.h" |
| #include "mlib_ImageCopy.h" |
| #include "mlib_v_ImageCopy_f.h" |
| |
| #define VIS_ALIGNADDR(X, Y) vis_alignaddr((void *)(X), Y) |
| |
| /***************************************************************/ |
| /* |
| * Both source and destination image data are 1-d vectors and |
| * 8-byte aligned. And size is in 8-bytes. |
| */ |
| |
| void mlib_v_ImageCopy_a1(mlib_d64 *sp, |
| mlib_d64 *dp, |
| mlib_s32 size) |
| { |
| mlib_s32 i; |
| |
| #pragma pipeloop(0) |
| for (i = 0; i < size; i++) { |
| *dp++ = *sp++; |
| } |
| } |
| |
| /***************************************************************/ |
| /* |
| * Either source or destination image data are not 1-d vectors, but |
| * they are 8-byte aligned. And stride and width are in 8-bytes. |
| */ |
| |
| void mlib_v_ImageCopy_a2(mlib_d64 *sp, |
| mlib_d64 *dp, |
| mlib_s32 width, |
| mlib_s32 height, |
| mlib_s32 stride, |
| mlib_s32 dstride) |
| { |
| mlib_d64 *spl; /* 8-byte aligned pointer for line */ |
| mlib_d64 *dpl; /* 8-byte aligned pointer for line */ |
| mlib_s32 i, j; /* indices for x, y */ |
| |
| spl = sp; |
| dpl = dp; |
| |
| /* row loop */ |
| for (j = 0; j < height; j++) { |
| /* 8-byte column loop */ |
| #pragma pipeloop(0) |
| for (i = 0; i < width; i++) { |
| *dp++ = *sp++; |
| } |
| |
| sp = spl += stride; |
| dp = dpl += dstride; |
| } |
| } |
| |
| /***************************************************************/ |
| /* |
| * Both bit offsets of source and distination are the same |
| */ |
| |
| void mlib_ImageCopy_bit_al(const mlib_u8 *sa, |
| mlib_u8 *da, |
| mlib_s32 size, |
| mlib_s32 offset) |
| { |
| mlib_u8 *dend; /* end points in dst */ |
| mlib_d64 *dp; /* 8-byte aligned start points in dst */ |
| mlib_d64 *sp; /* 8-byte aligned start point in src */ |
| mlib_d64 s0, s1; /* 8-byte source data */ |
| mlib_s32 j; /* offset of address in dst */ |
| mlib_s32 emask; /* edge mask */ |
| mlib_s32 b_size; /* size in bytes */ |
| mlib_u8 mask0 = 0xFF; |
| mlib_u8 src, mask; |
| |
| if (size <- 0) return; |
| |
| if (size < (8 - offset)) { |
| mask = mask0 << (8 - size); |
| mask >>= offset; |
| src = da[0]; |
| da[0] = (src & (~mask)) | (sa[0] & mask); |
| return; |
| } |
| |
| mask = mask0 >> offset; |
| src = da[0]; |
| da[0] = (src & (~mask)) | (sa[0] & mask); |
| da++; |
| sa++; |
| size = size - 8 + offset; |
| b_size = size >> 3; /* size in bytes */ |
| |
| /* prepare the destination addresses */ |
| dp = (mlib_d64 *) ((mlib_addr) da & (~7)); |
| j = (mlib_addr) dp - (mlib_addr) da; |
| dend = da + b_size - 1; |
| |
| /* prepare the source address */ |
| sp = (mlib_d64 *) VIS_ALIGNADDR(sa, j); |
| /* generate edge mask for the start point */ |
| emask = vis_edge8(da, dend); |
| |
| s1 = vis_ld_d64_nf(sp); |
| if (emask != 0xff) { |
| s0 = s1; |
| s1 = vis_ld_d64_nf(sp+1); |
| s0 = vis_faligndata(s0, s1); |
| vis_pst_8(s0, dp++, emask); |
| sp++; |
| j += 8; |
| } |
| |
| #pragma pipeloop(0) |
| for (; j <= (b_size - 8); j += 8) { |
| s0 = s1; |
| s1 = vis_ld_d64_nf(sp+1); |
| *dp++ = vis_faligndata(s0, s1); |
| sp++; |
| } |
| |
| if (j < b_size) { |
| s0 = vis_faligndata(s1, vis_ld_d64_nf(sp+1)); |
| emask = vis_edge8(dp, dend); |
| vis_pst_8(s0, dp, emask); |
| } |
| |
| j = size & 7; |
| |
| if (j > 0) { |
| mask = mask0 << (8 - j); |
| src = dend[1]; |
| dend[1] = (src & (~mask)) | (sa[b_size] & mask); |
| } |
| } |
| |
| /***************************************************************/ |
| /* |
| * Either source or destination data are not 8-byte aligned. |
| * And size is in bytes. |
| */ |
| |
| void mlib_ImageCopy_na(const mlib_u8 *sa, |
| mlib_u8 *da, |
| mlib_s32 size) |
| { |
| mlib_u8 *dend; /* end points in dst */ |
| mlib_d64 *dp; /* 8-byte aligned start points in dst */ |
| mlib_d64 *sp; /* 8-byte aligned start point in src */ |
| mlib_d64 s0, s1; /* 8-byte source data */ |
| mlib_s32 j; /* offset of address in dst */ |
| mlib_s32 emask; /* edge mask */ |
| |
| /* prepare the destination addresses */ |
| dp = (mlib_d64 *) ((mlib_addr) da & (~7)); |
| j = (mlib_addr) dp - (mlib_addr) da; |
| dend = da + size - 1; |
| |
| /* prepare the source address */ |
| sp = (mlib_d64 *) VIS_ALIGNADDR(sa, j); |
| /* generate edge mask for the start point */ |
| emask = vis_edge8(da, dend); |
| |
| s1 = vis_ld_d64_nf(sp); |
| if (emask != 0xff) { |
| s0 = s1; |
| s1 = vis_ld_d64_nf(sp+1); |
| s0 = vis_faligndata(s0, s1); |
| vis_pst_8(s0, dp++, emask); |
| sp++; |
| j += 8; |
| } |
| |
| if (((mlib_addr) sa ^ (mlib_addr) da) & 7) { |
| #pragma pipeloop(0) |
| for (; j <= (size - 8); j += 8) { |
| s0 = s1; |
| s1 = vis_ld_d64_nf(sp+1); |
| *dp++ = vis_faligndata(s0, s1); |
| sp++; |
| } |
| |
| if (j < size) { |
| s0 = vis_faligndata(s1, vis_ld_d64_nf(sp+1)); |
| emask = vis_edge8(dp, dend); |
| vis_pst_8(s0, dp, emask); |
| } |
| } |
| else { |
| #pragma pipeloop(0) |
| for (; j <= (size - 8); j += 8) { |
| *dp++ = *sp++; |
| } |
| |
| if (j < size) { |
| emask = vis_edge8(dp, dend); |
| vis_pst_8(vis_ld_d64_nf(sp), dp, emask); |
| } |
| } |
| } |
| |
| /***************************************************************/ |