Path: blob/master/src/java.desktop/share/native/libmlib_image/mlib_ImageLookUp_Bit.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_ImageLookUp_Bit_U8 - table lookup29*30* SYNOPSIS31* void mlib_ImageLookUp_Bit_U8(src, slb,32* dst, dlb,33* xsize, ysize,34* csize, table)35*36* ARGUMENT37* src pointer to input image (BIT)38* slb stride of input image (in pixels)39* dst pointer to output image (BYTE)40* dlb stride of output image (in pixels)41* xsize image width42* ysize image height43* csize number of channels44* table lookup table45*46* DESCRIPTION47* dst = table[src] (c, vis version)48*/4950#include "mlib_image.h"51#include "mlib_ImageLookUp.h"5253/***************************************************************/54#define MAX_WIDTH 5125556/***************************************************************/57#ifdef i386 /* do not copy by double data type for x86 */5859typedef struct {60mlib_u32 int0, int1;61} two_uint;6263#define TYPE_64BIT two_uint64#define TYPE_32BIT mlib_u3265#define DTYPE two_uint6667#elif defined(_NO_LONGLONG)6869#define TYPE_64BIT mlib_d6470#define TYPE_32BIT mlib_f3271#define DTYPE mlib_d647273#else7475#define TYPE_64BIT mlib_d6476#define TYPE_32BIT mlib_f3277#define DTYPE mlib_u647879#endif /* i386 ( do not copy by double data type for x86 ) */8081/***************************************************************/82typedef union {83TYPE_64BIT d64;84struct {85TYPE_32BIT f0, f1;86} f32s;87} d64_2_f32;8889/***************************************************************/90#ifdef _LITTLE_ENDIAN9192static const mlib_u32 mlib_bit_mask[16] = {930x00000000u, 0xFF000000u, 0x00FF0000u, 0xFFFF0000u,940x0000FF00u, 0xFF00FF00u, 0x00FFFF00u, 0xFFFFFF00u,950x000000FFu, 0xFF0000FFu, 0x00FF00FFu, 0xFFFF00FFu,960x0000FFFFu, 0xFF00FFFFu, 0x00FFFFFFu, 0xFFFFFFFFu97};9899static const mlib_u32 mlib_bit_mask_2[4] = {1000x00000000u, 0xFFFF0000u, 0x0000FFFFu, 0xFFFFFFFFu101};102103static const mlib_u32 mlib_bit_mask_3[3*4] = {1040x00000000u, 0xFF000000u, 0x00FFFFFFu, 0xFFFFFFFFu,1050x00000000u, 0xFFFF0000u, 0x0000FFFFu, 0xFFFFFFFFu,1060x00000000u, 0xFFFFFF00u, 0x000000FFu, 0xFFFFFFFFu107};108109#else110111static const mlib_u32 mlib_bit_mask[16] = {1120x00000000u, 0x000000FFu, 0x0000FF00u, 0x0000FFFFu,1130x00FF0000u, 0x00FF00FFu, 0x00FFFF00u, 0x00FFFFFFu,1140xFF000000u, 0xFF0000FFu, 0xFF00FF00u, 0xFF00FFFFu,1150xFFFF0000u, 0xFFFF00FFu, 0xFFFFFF00u, 0xFFFFFFFFu116};117118static const mlib_u32 mlib_bit_mask_2[4] = {1190x00000000u, 0x0000FFFFu, 0xFFFF0000u, 0xFFFFFFFFu120};121122static const mlib_u32 mlib_bit_mask_3[3*4] = {1230x00000000u, 0x000000FFu, 0xFFFFFF00u, 0xFFFFFFFFu,1240x00000000u, 0x0000FFFFu, 0xFFFF0000u, 0xFFFFFFFFu,1250x00000000u, 0x00FFFFFFu, 0xFF000000u, 0xFFFFFFFFu126};127128#endif /* _LITTLE_ENDIAN */129130/***************************************************************/131mlib_status mlib_ImageLookUp_Bit_U8_1(const mlib_u8 *src,132mlib_s32 slb,133mlib_u8 *dst,134mlib_s32 dlb,135mlib_s32 xsize,136mlib_s32 ysize,137mlib_s32 nchan,138mlib_s32 bitoff,139const mlib_u8 **table)140{141mlib_s32 i, j, n;142TYPE_64BIT dd_array[256];143mlib_u8 buff_lcl[MAX_WIDTH/8];144mlib_u8 *buff = (mlib_u8*)buff_lcl;145mlib_u32 val0, val1, *p_dd = (mlib_u32*)dd_array;146147if (xsize > MAX_WIDTH) {148buff = mlib_malloc((xsize + 7)/8);149150if (buff == NULL) return MLIB_FAILURE;151}152153val0 = table[0][0];154val1 = table[0][1];155val0 |= (val0 << 8);156val1 |= (val1 << 8);157val0 |= (val0 << 16);158val1 |= (val1 << 16);159160/* calculate lookup table */161for (i = 0; i < 16; i++) {162mlib_u32 v, mask = mlib_bit_mask[i];163164v = (val0 &~ mask) | (val1 & mask);165166for (j = 0; j < 16; j++) {167p_dd[2*(16*i + j)] = v;168}169170for (j = 0; j < 16; j++) {171p_dd[2*(i + 16*j) + 1] = v;172}173}174175for (j = 0; j < ysize; j++) {176mlib_s32 s0, size = xsize;177mlib_u8 *dp = dst;178mlib_u8 *sp = (void *)src;179mlib_u8 *sa;180TYPE_64BIT *da;181mlib_s32 doff, boff = bitoff;182183if ((mlib_addr)dp & 7) {184185/* result of (dp & 7) certainly fits into mlib_s32 */186doff = 8 - ((mlib_s32) ((mlib_addr)dp & 7));187188if (doff > xsize) doff = xsize;189190for (n = 0; n < doff; n++) {191dp[n] = table[0][(sp[0] >> (7 - boff)) & 0x1];192boff++;193194if (boff >= 8) {195sp++;196boff -= 8;197}198199size--;200}201202dp += doff;203}204205if (boff) {206mlib_ImageCopy_bit_na(sp, buff, size, boff, 0);207sp = buff;208}209210sa = (mlib_u8*)sp;211da = (TYPE_64BIT*)dp;212i = 0;213214if ((mlib_addr)sa & 1 && size >= 8) {215*da++ = dd_array[*sa++];216i += 8;217}218219for (; i <= (size - 16); i += 16) {220s0 = *(mlib_u16*)sa;221#ifdef _LITTLE_ENDIAN222*da++ = dd_array[s0 & 0xFF];223*da++ = dd_array[s0 >> 8];224#else225*da++ = dd_array[s0 >> 8];226*da++ = dd_array[s0 & 0xFF];227#endif /* _LITTLE_ENDIAN */228sa += 2;229}230231if (i <= (size - 8)) {232*da++ = dd_array[*sa++];233i += 8;234}235236if (i < size) {237238#ifdef _NO_LONGLONG239240mlib_u32 emask;241val0 = sa[0];242val1 = p_dd[2*val0];243244if (i < (size - 4)) {245((mlib_u32*)da)[0] = val1;246da = (TYPE_64BIT *) ((mlib_u8 *)da + 4);247i += 4;248val1 = p_dd[2*val0+1];249}250251#ifdef _LITTLE_ENDIAN252emask = (~(mlib_u32)0) >> ((4 - (size - i)) * 8);253#else254emask = (~(mlib_u32)0) << ((4 - (size - i)) * 8);255#endif /* _LITTLE_ENDIAN */256((mlib_u32*)da)[0] = (val1 & emask) | (((mlib_u32*)da)[0] &~ emask);257258#else /* _NO_LONGLONG */259260#ifdef _LITTLE_ENDIAN261mlib_u64 emask = (~(mlib_u64)0) >> ((8 - (size - i)) * 8);262#else263mlib_u64 emask = (~(mlib_u64)0) << ((8 - (size - i)) * 8);264#endif /* _LITTLE_ENDIAN */265266((mlib_u64*)da)[0] = (((mlib_u64*)dd_array)[sa[0]] & emask) | (((mlib_u64*)da)[0] &~ emask);267268#endif /* _NO_LONGLONG */269}270271src += slb;272dst += dlb;273}274275if (buff != (mlib_u8*)buff_lcl) mlib_free(buff);276277return MLIB_SUCCESS;278}279280/***************************************************************/281mlib_status mlib_ImageLookUp_Bit_U8_2(const mlib_u8 *src,282mlib_s32 slb,283mlib_u8 *dst,284mlib_s32 dlb,285mlib_s32 xsize,286mlib_s32 ysize,287mlib_s32 nchan,288mlib_s32 bitoff,289const mlib_u8 **table)290{291mlib_s32 i, j;292mlib_s32 s0, size;293#ifdef _NO_LONGLONG294mlib_u32 emask, dd1, dd2;295#else /* _NO_LONGLONG */296mlib_u64 emask, dd;297#endif /* _NO_LONGLONG */298DTYPE dd_array[16];299mlib_u32 *p_dd = (mlib_u32*)dd_array;300mlib_d64 buff_lcl[(MAX_WIDTH + MAX_WIDTH/8)/8];301mlib_u8 *buff = (mlib_u8*)buff_lcl, *buffs;302mlib_u32 val0, val1;303304size = xsize * 2;305306if (size > MAX_WIDTH) {307buff = mlib_malloc(size + (size + 7)/8);308309if (buff == NULL) return MLIB_FAILURE;310}311312buffs = buff + size;313314val0 = table[0][0];315val1 = table[0][1];316#ifdef _LITTLE_ENDIAN317val0 = val0 | (table[1][0] << 8);318val1 = val1 | (table[1][1] << 8);319#else320val0 = (val0 << 8) | table[1][0];321val1 = (val1 << 8) | table[1][1];322#endif /* _LITTLE_ENDIAN */323val0 |= (val0 << 16);324val1 |= (val1 << 16);325326/* calculate lookup table */327for (i = 0; i < 4; i++) {328mlib_u32 v, mask = mlib_bit_mask_2[i];329330v = (val0 &~ mask) | (val1 & mask);331332for (j = 0; j < 4; j++) {333p_dd[2*(4*i + j)] = v;334p_dd[2*(i + 4*j) + 1] = v;335}336}337338for (j = 0; j < ysize; j++) {339mlib_u8 *dp = dst;340mlib_u8 *sp = (void *)src;341mlib_u8 *sa;342DTYPE *da;343344if ((mlib_addr)dp & 7) dp = buff;345346if (bitoff) {347mlib_ImageCopy_bit_na(sp, buffs, size, bitoff, 0);348sp = buffs;349}350351sa = (mlib_u8*)sp;352da = (DTYPE*)dp;353354for (i = 0; i <= (size - 16); i += 16) {355s0 = *sa++;356*da++ = dd_array[s0 >> 4];357*da++ = dd_array[s0 & 0xF];358}359360if (i < size) {361s0 = *sa++;362363#ifdef _NO_LONGLONG364365dd1 = p_dd[2*(s0 >> 4)];366dd2 = p_dd[2*(s0 >> 4)+1];367368if (i < (size - 8)) {369((mlib_u32*)da)[0] = dd1;370((mlib_u32*)da)[1] = dd2;371da++;372i += 8;373dd1 = p_dd[2*(s0 & 0xf)];374dd2 = p_dd[2*(s0 & 0xf)+1];375}376377if (i < (size - 4)) {378((mlib_u32*)da)[0] = dd1;379da = (DTYPE *) ((mlib_u8 *)da + 4);380i += 4;381dd1 = dd2;382}383384#ifdef _LITTLE_ENDIAN385emask = (~(mlib_u32)0) >> ((4 - (size - i)) * 8);386#else387emask = (~(mlib_u32)0) << ((4 - (size - i)) * 8);388#endif /* _LITTLE_ENDIAN */389((mlib_u32*)da)[0] = (dd1 & emask) | (((mlib_u32*)da)[0] &~ emask);390391#else /* _NO_LONGLONG */392393dd = ((mlib_u64*)dd_array)[s0 >> 4];394395if (i < (size - 8)) {396((mlib_u64*)da)[0] = dd;397da++;398i += 8;399dd = ((mlib_u64*)dd_array)[s0 & 0xf];400}401402#ifdef _LITTLE_ENDIAN403emask = (~(mlib_u64)0) >> ((8 - (size - i)) * 8);404#else405emask = (~(mlib_u64)0) << ((8 - (size - i)) * 8);406#endif /* _LITTLE_ENDIAN */407((mlib_u64*)da)[0] = (dd & emask) | (((mlib_u64*)da)[0] &~ emask);408409#endif /* _NO_LONGLONG */410}411412if (dp != dst) mlib_ImageCopy_na(dp, dst, size);413414src += slb;415dst += dlb;416}417418if (buff != (mlib_u8*)buff_lcl) mlib_free(buff);419420return MLIB_SUCCESS;421}422423/***************************************************************/424mlib_status mlib_ImageLookUp_Bit_U8_3(const mlib_u8 *src,425mlib_s32 slb,426mlib_u8 *dst,427mlib_s32 dlb,428mlib_s32 xsize,429mlib_s32 ysize,430mlib_s32 nchan,431mlib_s32 bitoff,432const mlib_u8 **table)433{434mlib_s32 i, j;435mlib_s32 s0, size;436mlib_u32 emask, dd;437TYPE_64BIT d_array01[16], d_array12[16];438TYPE_64BIT buff_lcl[(MAX_WIDTH + MAX_WIDTH/8)/8];439mlib_u8 *buff = (mlib_u8*)buff_lcl, *buffs;440mlib_u32 l0, h0, v0, l1, h1, v1, l2, h2, v2;441442size = 3 * xsize;443444if (size > MAX_WIDTH) {445buff = mlib_malloc(size + (size + 7)/8);446447if (buff == NULL) return MLIB_FAILURE;448}449450buffs = buff + size;451452#ifdef _LITTLE_ENDIAN453l0 = (table[0][0] << 24) | (table[2][0] << 16) | (table[1][0] << 8) | (table[0][0]);454h0 = (table[0][1] << 24) | (table[2][1] << 16) | (table[1][1] << 8) | (table[0][1]);455l1 = (l0 >> 8); l1 |= (l1 << 24);456h1 = (h0 >> 8); h1 |= (h1 << 24);457l2 = (l1 >> 8); l2 |= (l2 << 24);458h2 = (h1 >> 8); h2 |= (h2 << 24);459#else460l0 = (table[0][0] << 24) | (table[1][0] << 16) | (table[2][0] << 8) | (table[0][0]);461h0 = (table[0][1] << 24) | (table[1][1] << 16) | (table[2][1] << 8) | (table[0][1]);462l1 = (l0 << 8); l1 |= (l1 >> 24);463h1 = (h0 << 8); h1 |= (h1 >> 24);464l2 = (l1 << 8); l2 |= (l2 >> 24);465h2 = (h1 << 8); h2 |= (h2 >> 24);466#endif /* _LITTLE_ENDIAN */467468/* calculate lookup table */469for (i = 0; i < 16; i++) {470mlib_u32 mask0 = mlib_bit_mask_3[i >> 2];471mlib_u32 mask1 = mlib_bit_mask_3[4 + ((i >> 1) & 3)];472mlib_u32 mask2 = mlib_bit_mask_3[8 + (i & 3)];473474v0 = (l0 &~ mask0) | (h0 & mask0);475v1 = (l1 &~ mask1) | (h1 & mask1);476v2 = (l2 &~ mask2) | (h2 & mask2);477478((mlib_u32*)d_array01)[2*i ] = v0;479((mlib_u32*)d_array01)[2*i + 1] = v1;480((mlib_u32*)d_array12)[2*i ] = v1;481((mlib_u32*)d_array12)[2*i + 1] = v2;482}483484for (j = 0; j < ysize; j++) {485mlib_u8 *dp = dst;486mlib_u8 *sp = (void *)src;487mlib_u8 *sa;488mlib_u32 *da;489490if ((mlib_addr)dp & 7) dp = buff;491492if (bitoff) {493mlib_ImageCopy_bit_na(sp, buffs, size, bitoff, 0);494sp = buffs;495}496497sa = (mlib_u8*)sp;498da = (mlib_u32*)dp;499500for (i = 0; i <= (size - 24); i += 24) {501d64_2_f32 dd;502s0 = *sa++;503504((TYPE_64BIT*)da)[0] = *(d_array01 + (s0 >> 4));505506dd.f32s.f0 = ((TYPE_32BIT*)(d_array12 + (s0 >> 4)))[1];507dd.f32s.f1 = ((TYPE_32BIT*)(d_array01 + (s0 & 0xF)))[0];508((TYPE_64BIT*)da)[1] = dd.d64;509((TYPE_64BIT*)da)[2] = *(d_array12 + (s0 & 0xF));510511da += 6;512}513514if (i < size) {515s0 = *sa++;516dd = ((mlib_u32*)(d_array01 + (s0 >> 4)))[0];517518if (i < (size - 4)) {519*da++ = dd;520i += 4;521dd = ((mlib_u32*)(d_array12 + (s0 >> 4)))[0];522}523524if (i < (size - 4)) {525*da++ = dd;526i += 4;527dd = ((mlib_u32*)(d_array12 + (s0 >> 4)))[1];528}529530if (i < (size - 4)) {531*da++ = dd;532i += 4;533dd = ((mlib_u32*)(d_array01 + (s0 & 0xF)))[0];534}535536if (i < (size - 4)) {537*da++ = dd;538i += 4;539dd = ((mlib_u32*)(d_array12 + (s0 & 0xF)))[0];540}541542if (i < (size - 4)) {543*da++ = dd;544i += 4;545dd = ((mlib_u32*)(d_array12 + (s0 & 0xF)))[1];546}547548#ifdef _LITTLE_ENDIAN549emask = (~(mlib_u32)0) >> ((4 - (size - i)) * 8);550#else551emask = (~(mlib_u32)0) << ((4 - (size - i)) * 8);552#endif /* _LITTLE_ENDIAN */553da[0] = (dd & emask) | (da[0] &~ emask);554}555556if (dp != dst) mlib_ImageCopy_na(dp, dst, size);557558src += slb;559dst += dlb;560}561562if (buff != (mlib_u8*)buff_lcl) mlib_free(buff);563564return MLIB_SUCCESS;565}566567/***************************************************************/568mlib_status mlib_ImageLookUp_Bit_U8_4(const mlib_u8 *src,569mlib_s32 slb,570mlib_u8 *dst,571mlib_s32 dlb,572mlib_s32 xsize,573mlib_s32 ysize,574mlib_s32 nchan,575mlib_s32 bitoff,576const mlib_u8 **table)577{578mlib_s32 i, j;579mlib_s32 s0, size;580DTYPE dd_array0[16], dd_array1[16], lh[4], dd;581mlib_d64 buff_lcl[(MAX_WIDTH + MAX_WIDTH/8)/8];582mlib_u8 *buff = (mlib_u8*)buff_lcl, *buffs;583mlib_u32 l, h;584585size = xsize * 4;586587if (size > MAX_WIDTH) {588buff = mlib_malloc(size + (size + 7)/8);589590if (buff == NULL) return MLIB_FAILURE;591}592593buffs = buff + size;594595#ifdef _LITTLE_ENDIAN596l = (table[3][0] << 24) | (table[2][0] << 16) | (table[1][0] << 8) | (table[0][0]);597h = (table[3][1] << 24) | (table[2][1] << 16) | (table[1][1] << 8) | (table[0][1]);598#else599l = (table[0][0] << 24) | (table[1][0] << 16) | (table[2][0] << 8) | (table[3][0]);600h = (table[0][1] << 24) | (table[1][1] << 16) | (table[2][1] << 8) | (table[3][1]);601#endif /* _LITTLE_ENDIAN */602603((mlib_u32*)lh)[0] = l; ((mlib_u32*)lh)[1] = l;604((mlib_u32*)lh)[2] = l; ((mlib_u32*)lh)[3] = h;605((mlib_u32*)lh)[4] = h; ((mlib_u32*)lh)[5] = l;606((mlib_u32*)lh)[6] = h; ((mlib_u32*)lh)[7] = h;607608/* calculate lookup table */609dd_array0[ 0] = lh[0]; dd_array1[ 0] = lh[0];610dd_array0[ 1] = lh[0]; dd_array1[ 1] = lh[1];611dd_array0[ 2] = lh[0]; dd_array1[ 2] = lh[2];612dd_array0[ 3] = lh[0]; dd_array1[ 3] = lh[3];613dd_array0[ 4] = lh[1]; dd_array1[ 4] = lh[0];614dd_array0[ 5] = lh[1]; dd_array1[ 5] = lh[1];615dd_array0[ 6] = lh[1]; dd_array1[ 6] = lh[2];616dd_array0[ 7] = lh[1]; dd_array1[ 7] = lh[3];617dd_array0[ 8] = lh[2]; dd_array1[ 8] = lh[0];618dd_array0[ 9] = lh[2]; dd_array1[ 9] = lh[1];619dd_array0[10] = lh[2]; dd_array1[10] = lh[2];620dd_array0[11] = lh[2]; dd_array1[11] = lh[3];621dd_array0[12] = lh[3]; dd_array1[12] = lh[0];622dd_array0[13] = lh[3]; dd_array1[13] = lh[1];623dd_array0[14] = lh[3]; dd_array1[14] = lh[2];624dd_array0[15] = lh[3]; dd_array1[15] = lh[3];625626for (j = 0; j < ysize; j++) {627mlib_u8 *dp = dst;628mlib_u8 *sp = (void *)src;629mlib_u8 *sa;630DTYPE *da;631632if ((mlib_addr)dp & 7) dp = buff;633634if (bitoff) {635mlib_ImageCopy_bit_na(sp, buffs, size, bitoff, 0);636sp = buffs;637}638639sa = (mlib_u8*)sp;640da = (DTYPE*)dp;641642for (i = 0; i <= (size - 32); i += 32) {643s0 = *sa++;644*da++ = dd_array0[s0 >> 4];645*da++ = dd_array1[s0 >> 4];646*da++ = dd_array0[s0 & 0xF];647*da++ = dd_array1[s0 & 0xF];648}649650if (i < size) {651s0 = *sa++;652dd = dd_array0[s0 >> 4];653654if (i <= (size - 8)) {655*da++ = dd;656i += 8;657dd = dd_array1[s0 >> 4];658}659660if (i <= (size - 8)) {661*da++ = dd;662i += 8;663dd = dd_array0[s0 & 0xF];664}665666if (i <= (size - 8)) {667*da++ = dd;668i += 8;669dd = dd_array1[s0 & 0xF];670}671672if (i < size) {673*(mlib_u32*)da = *(mlib_u32*) & dd;674}675}676677if (dp != dst) mlib_ImageCopy_na(dp, dst, size);678679src += slb;680dst += dlb;681}682683if (buff != (mlib_u8*)buff_lcl) mlib_free(buff);684685return MLIB_SUCCESS;686}687688/***************************************************************/689690691