diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:30:08 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:30:08 -0800 |
commit | 7f81d9b6fa7f2ec161b682622db577a28c90b49f (patch) | |
tree | daaa0044f81c7c8c0f867a5c35e709c1d2fcf82a | |
parent | dceec766d86853b64ead319bf97648d9fc8301e6 (diff) | |
download | neven-cupcake.tar.gz |
auto import from //depot/cupcake/@135843android-sdk-tools_r2android-sdk-1.6_r2android-sdk-1.6_r1android-sdk-1.6-docs_r1android-sdk-1.5_r3android-sdk-1.5_r1android-sdk-1.5-preandroid-1.6_r2android-1.6_r1.5android-1.6_r1.4android-1.6_r1.3android-1.6_r1.2android-1.6_r1.1android-1.6_r1android-1.5r4android-1.5r3android-1.5r2android-1.5donut-release2donut-releasedonutcupcake-releasecupcake
189 files changed, 43539 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..e223867 --- /dev/null +++ b/Android.mk @@ -0,0 +1,136 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + FaceDetector_jni.cpp \ + Embedded/common/src/b_APIEm/DCR.c \ + Embedded/common/src/b_APIEm/BFFaceFinder.c \ + Embedded/common/src/b_APIEm/FaceFinder.c \ + Embedded/common/src/b_APIEm/FaceFinderRef.c \ + Embedded/common/src/b_APIEm/Functions.c \ + Embedded/common/src/b_BasicEm/APh.c \ + Embedded/common/src/b_BasicEm/APhArr.c \ + Embedded/common/src/b_BasicEm/Complex.c \ + Embedded/common/src/b_BasicEm/ComplexArr.c \ + Embedded/common/src/b_BasicEm/Context.c \ + Embedded/common/src/b_BasicEm/DynMemManager.c \ + Embedded/common/src/b_BasicEm/Functions.c \ + Embedded/common/src/b_BasicEm/Int16Arr.c \ + Embedded/common/src/b_BasicEm/Int32Arr.c \ + Embedded/common/src/b_BasicEm/Int8Arr.c \ + Embedded/common/src/b_BasicEm/Math.c.arm \ + Embedded/common/src/b_BasicEm/MemSeg.c \ + Embedded/common/src/b_BasicEm/MemTbl.c \ + Embedded/common/src/b_BasicEm/Memory.c \ + Embedded/common/src/b_BasicEm/Phase.c \ + Embedded/common/src/b_BasicEm/String.c \ + Embedded/common/src/b_BasicEm/UInt16Arr.c \ + Embedded/common/src/b_BasicEm/UInt32Arr.c \ + Embedded/common/src/b_BasicEm/UInt8Arr.c \ + Embedded/common/src/b_BitFeatureEm/BitParam.c \ + Embedded/common/src/b_BitFeatureEm/Feature.c \ + Embedded/common/src/b_BitFeatureEm/Functions.c \ + Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.c \ + Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.c \ + Embedded/common/src/b_BitFeatureEm/LocalScanDetector.c \ + Embedded/common/src/b_BitFeatureEm/LocalScanner.c \ + Embedded/common/src/b_BitFeatureEm/ScanDetector.c \ + Embedded/common/src/b_BitFeatureEm/Scanner.c \ + Embedded/common/src/b_BitFeatureEm/Sequence.c \ + Embedded/common/src/b_ImageEm/APhImage.c \ + Embedded/common/src/b_ImageEm/ComplexImage.c \ + Embedded/common/src/b_ImageEm/Flt16Image.c \ + Embedded/common/src/b_ImageEm/Functions.c \ + Embedded/common/src/b_ImageEm/HistoEq.c \ + Embedded/common/src/b_ImageEm/UInt16ByteImage.c \ + Embedded/common/src/b_ImageEm/UInt16BytePyrImage.c \ + Embedded/common/src/b_ImageEm/UInt8Image.c \ + Embedded/common/src/b_ImageEm/UInt32Image.c \ + Embedded/common/src/b_ImageEm/UInt8PyramidalImage.c \ + Embedded/common/src/b_TensorEm/Alt.c \ + Embedded/common/src/b_TensorEm/Cluster2D.c \ + Embedded/common/src/b_TensorEm/Cluster3D.c \ + Embedded/common/src/b_TensorEm/CompactAlt.c \ + Embedded/common/src/b_TensorEm/CompactMat.c \ + Embedded/common/src/b_TensorEm/Flt16Alt2D.c \ + Embedded/common/src/b_TensorEm/Flt16Alt3D.c \ + Embedded/common/src/b_TensorEm/Flt16Mat2D.c \ + Embedded/common/src/b_TensorEm/Flt16Mat3D.c \ + Embedded/common/src/b_TensorEm/Flt16Vec.c \ + Embedded/common/src/b_TensorEm/Flt16Vec2D.c \ + Embedded/common/src/b_TensorEm/Flt16Vec3D.c \ + Embedded/common/src/b_TensorEm/Functions.c \ + Embedded/common/src/b_TensorEm/IdCluster2D.c \ + Embedded/common/src/b_TensorEm/Int16Mat2D.c \ + Embedded/common/src/b_TensorEm/Int16Rect.c \ + Embedded/common/src/b_TensorEm/Int16Vec2D.c \ + Embedded/common/src/b_TensorEm/Int16Vec3D.c \ + Embedded/common/src/b_TensorEm/Int32Mat.c \ + Embedded/common/src/b_TensorEm/MapSequence.c \ + Embedded/common/src/b_TensorEm/Mat.c \ + Embedded/common/src/b_TensorEm/Normalizer.c \ + Embedded/common/src/b_TensorEm/RBFMap2D.c \ + Embedded/common/src/b_TensorEm/SubVecMap.c \ + Embedded/common/src/b_TensorEm/Uint32Rect.c \ + Embedded/common/src/b_TensorEm/VectorMap.c \ + FaceRecEm/common/src/b_FDSDK/DCR.c \ + FaceRecEm/common/src/b_FDSDK/FaceFinder.c \ + FaceRecEm/common/src/b_FDSDK/SDK.c +## + +LOCAL_CFLAGS += -Depl_LINUX + +LOCAL_C_INCLUDES += \ + external/neven/FaceRecEm/common/src/b_FDSDK \ + $(JNI_H_INCLUDE) \ + $(call include-path-for, corecg graphics) \ + $(LOCAL_PATH)/FaceRecEm/common/src \ + $(LOCAL_PATH)/Embedded/common/conf \ + $(LOCAL_PATH)/Embedded/common/src \ + $(LOCAL_PATH)/unix/src + +LOCAL_SHARED_LIBRARIES := \ + libandroid_runtime \ + libnativehelper \ + libutils \ + libcorecg \ + libsgl \ + libcutils + +LOCAL_MODULE:= libFFTEm + +ALL_PREBUILT += $(TARGET_OUT)/usr/share/bmd/RFFspeed_501.bmd +$(TARGET_OUT)/usr/share/bmd/RFFspeed_501.bmd : $(LOCAL_PATH)/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd | $(ACP) + $(transform-prebuilt-to-target) + +ALL_PREBUILT += $(TARGET_OUT)/usr/share/bmd/RFFstd_501.bmd +$(TARGET_OUT)/usr/share/bmd/RFFstd_501.bmd : $(LOCAL_PATH)/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd | $(ACP) + $(transform-prebuilt-to-target) + + +include $(BUILD_SHARED_LIBRARY) diff --git a/Embedded/common/conf/b_BasicEm/LibConfig.h b/Embedded/common/conf/b_BasicEm/LibConfig.h new file mode 100644 index 0000000..dfe8e12 --- /dev/null +++ b/Embedded/common/conf/b_BasicEm/LibConfig.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_LIB_CONFIG_H +#define bbs_LIB_CONFIG_H + +/* ----------------- library tags --------------------------- */ + +/* ----------------- other tags ----------------------------- */ + +#define bbs_MINIMIZE_FRQ_IMG + +#define bbs_USE_FRQ_IMG_SYMMETRY + +/*#define bbs_COMPACT_MESSAGE_HANDLING*/ + +#define bbs_ENABLE_BIT_FEATURE + +#endif /* bbs_LIB_CONFIG_H */ diff --git a/Embedded/common/data/APIEm/Modules/RFFprec_501.bmd b/Embedded/common/data/APIEm/Modules/RFFprec_501.bmd Binary files differnew file mode 100644 index 0000000..00f96a6 --- /dev/null +++ b/Embedded/common/data/APIEm/Modules/RFFprec_501.bmd diff --git a/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd b/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd Binary files differnew file mode 100644 index 0000000..e7299a5 --- /dev/null +++ b/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd diff --git a/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd b/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd Binary files differnew file mode 100644 index 0000000..2187396 --- /dev/null +++ b/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd diff --git a/Embedded/common/src/b_APIEm/BFFaceFinder.c b/Embedded/common/src/b_APIEm/BFFaceFinder.c new file mode 100644 index 0000000..180d376 --- /dev/null +++ b/Embedded/common/src/b_APIEm/BFFaceFinder.c @@ -0,0 +1,499 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_APIEm/BFFaceFinder.h" +#include "b_APIEm/Functions.h" +#include "b_APIEm/DCR.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_init( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA ) +{ + bpi_FaceFinder_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bpi_FF_BF_FACE_FINDER; + ptrA->baseE.vpSetParamsE = bpi_BFFaceFinder_setParams; + ptrA->baseE.vpSetRangeE = bpi_BFFaceFinder_setRange; + ptrA->baseE.vpProcessE = bpi_BFFaceFinder_processDcr; + ptrA->baseE.vpPutDcrE = bpi_BFFaceFinder_putDcr; + ptrA->baseE.vpGetDcrE = bpi_BFFaceFinder_getDcr; + + ptrA->detectedFacesE = 0; + ptrA->availableFacesE = 0; + ptrA->faceDataBufferE = NULL; + bbf_ScanDetector_init( cpA, &ptrA->detectorE ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_exit( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA ) +{ + ptrA->detectedFacesE = 0; + ptrA->availableFacesE = 0; + ptrA->faceDataBufferE = NULL; + bbf_ScanDetector_exit( cpA, &ptrA->detectorE ); + + bpi_FaceFinder_exit( cpA, &ptrA->baseE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_copy( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + const struct bpi_BFFaceFinder* srcPtrA ) +{ + bpi_FaceFinder_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbf_ScanDetector_copy( cpA, &ptrA->detectorE, &srcPtrA->detectorE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bpi_BFFaceFinder_equal( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + const struct bpi_BFFaceFinder* srcPtrA ) +{ + if( !bpi_FaceFinder_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbf_ScanDetector_equal( cpA, &ptrA->detectorE, &srcPtrA->detectorE ) ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_getMinEyeDistance( const struct bpi_BFFaceFinder* ptrA ) +{ + return ( ( ptrA->detectorE.refDistanceE >> 8 ) * ( ptrA->detectorE.minScaleE >> 12 ) ) >> 16; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_getMaxEyeDistance( const struct bpi_BFFaceFinder* ptrA ) +{ + return ( ( ptrA->detectorE.refDistanceE >> 8 ) * ( ptrA->detectorE.maxScaleE >> 12 ) ) >> 16; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_setMinEyeDistance( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + uint32 distA ) +{ + ptrA->detectorE.minScaleE = ( ( distA << 16 ) / ( ptrA->detectorE.refDistanceE >> 8 ) ) << 12; + if( ptrA->detectorE.minScaleE < 0x100000 /* 1.0 */ ) ptrA->detectorE.minScaleE = 0x100000; +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_setMaxEyeDistance( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + uint32 distA ) +{ + if( distA > 0x0FFFF ) + { + ptrA->detectorE.maxScaleE = 0; /* unlimited */ + } + else + { + ptrA->detectorE.maxScaleE = ( ( distA << 16 ) / ( ptrA->detectorE.refDistanceE >> 8 ) ) << 12; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_memSize( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder *ptrA ) +{ + uint32 memSizeL = 0; + memSizeL += bbs_SIZEOF16( uint32 ); + memSizeL += bbs_SIZEOF16( uint32 ); /* version */ + memSizeL += bpi_FaceFinder_memSize( cpA, &ptrA->baseE ); + memSizeL += bbf_ScanDetector_memSize( cpA, &ptrA->detectorE ); + memSizeL += bbs_SIZEOF16( uint16 ); /* csa */ + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_memWrite( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bpi_BFFaceFinder_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bpi_BF_FACE_FINDER_VERSION, memPtrA ); + memPtrA += bpi_FaceFinder_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbf_ScanDetector_memWrite( cpA, &ptrA->detectorE, memPtrA ); + memPtrA += bpi_memWriteCsa16( memPtrA, memSizeL, 0xFFFF ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_memRead( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bpi_BF_FACE_FINDER_VERSION, memPtrA ); + memPtrA += bpi_FaceFinder_memRead( cpA, &ptrA->baseE, memPtrA ); + if( bbs_Context_error( cpA ) ) return 0; + + memPtrA += bbf_ScanDetector_memRead( cpA, &ptrA->detectorE, memPtrA, mtpA ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bpi_memReadCsa16( memPtrA ); + +/* if( memSizeL != bpi_BFFaceFinder_memSize( cpA, ptrA ) ) + { + bbs_ERROR0( "uint32 bpi_BFFaceFinder_memRead( .... ):\n" + "Module file is corrupt or incorrect. Please check if the face finder module is still supported." ); + return 0; + } +*/ + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bpi_BFFaceFinder_process( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA, + struct bts_Int16Vec2D* offsPtrA, + struct bts_IdCluster2D* idClusterPtrA ) +{ + int32 xL = 0; /* 16.16 */ + int32 yL = 0; /* 16.16 */ + uint32 scaleL = 0; + int32 actL = 0; + int32* outArrL; + + struct bts_Flt16Alt2D altL; + struct bts_Flt16Vec2D centerL; + + struct bpi_BFFaceFinder* ptrL = ( struct bpi_BFFaceFinder* )ptrA; + + /* reset multi face imformation so they are not accidentally used */ + ptrL->detectedFacesE = 0; + ptrL->availableFacesE = 0; + ptrL->faceDataBufferE = NULL; + + bbf_ScanDetector_process( cpA, ( struct bbf_ScanDetector* )&ptrA->detectorE, imagePtrA, imageWidthA, imageHeightA, roiPtrA, &outArrL ); + + xL = outArrL[ 0 ]; /* 16.16 */ + yL = outArrL[ 1 ]; /* 16.16 */ + scaleL = outArrL[ 2 ]; /* 12.20 */ + actL = outArrL[ 3 ]; /* 4.28 */ + + if( bbs_Context_error( cpA ) ) return 0; + + offsPtrA->xE = xL >> 16; + offsPtrA->yE = yL >> 16; + xL -= ( ( int32 )offsPtrA->xE << 16 ); + yL -= ( ( int32 )offsPtrA->yE << 16 ); + + centerL = bts_Flt16Vec2D_create32( 0, 0, 0 ); + altL = bts_Flt16Alt2D_createScale( scaleL, 20, ¢erL ); + altL.vecE = bts_Flt16Vec2D_create32( xL, yL, 16 ); + + /* compute cluster */ + { + uint32 eyeDistL = ( ( ptrA->detectorE.refDistanceE >> 16 ) * scaleL ) >> 20; + uint32 logEyeDistL = bbs_intLog2( eyeDistL ); + int32 bbpL = 11 - logEyeDistL; + bbpL = bbpL < 0 ? 0 : bbpL; + bbpL = bbpL > 6 ? 6 : bbpL; + bts_IdCluster2D_copyTransform( cpA, idClusterPtrA, &ptrA->detectorE.refClusterE, altL, bbpL ); + } + + + return ( actL + 0x10000000 ) >> 5; /*output range 0...1 in 8.24*/ +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_multiProcess( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA ) +{ + struct bpi_BFFaceFinder* ptrL = ( struct bpi_BFFaceFinder* )ptrA; + ptrL->detectedFacesE = bbf_ScanDetector_process( cpA, ( struct bbf_ScanDetector* )&ptrA->detectorE, imagePtrA, imageWidthA, imageHeightA, roiPtrA, &ptrL->faceDataBufferE ); + ptrL->availableFacesE = ptrA->detectedFacesE > 0 ? ptrA->detectedFacesE : 1; + if( bbs_Context_error( cpA ) ) return 0; + return ptrL->detectedFacesE; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_BFFaceFinder_getFace( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + uint32 indexA, + struct bts_Int16Vec2D* offsPtrA, + struct bts_IdCluster2D* idClusterPtrA ) +{ + bbs_DEF_fNameL( "bpi_BFFaceFinder_getFace" ) + int32 xL = 0; /* 16.16 */ + int32 yL = 0; /* 16.16 */ + uint32 scaleL = 0; + int32 actL = 0; + struct bts_Flt16Alt2D altL; + struct bts_Flt16Vec2D centerL; + + if( bbs_Context_error( cpA ) ) return 0; + + if( ptrA->availableFacesE == 0 || ptrA->faceDataBufferE == NULL ) + { + bbs_ERROR1( "%s:\nNo faces are availabe. This function was called before the face finder could detect multiple faces in an image", fNameL ); + return 0; + } + + if( indexA >= ptrA->availableFacesE ) + { + bbs_ERROR1( "%s:\nface index exceeds number of available faces", fNameL ); + return 0; + } + + xL = ptrA->faceDataBufferE[ indexA * 4 + 0 ]; /* 16.16 */ + yL = ptrA->faceDataBufferE[ indexA * 4 + 1 ]; /* 16.16 */ + scaleL = ptrA->faceDataBufferE[ indexA * 4 + 2 ]; /* 12.20 */ + actL = ptrA->faceDataBufferE[ indexA * 4 + 3 ]; /* 4.28 */ + + offsPtrA->xE = xL >> 16; + offsPtrA->yE = yL >> 16; + + xL -= ( ( int32 )offsPtrA->xE << 16 ); + yL -= ( ( int32 )offsPtrA->yE << 16 ); + + centerL = bts_Flt16Vec2D_create32( 0, 0, 0 ); + altL = bts_Flt16Alt2D_createScale( scaleL, 20, ¢erL ); + altL.vecE = bts_Flt16Vec2D_create32( xL, yL, 16 ); + + /* compute cluster */ + { + uint32 eyeDistL = ( ( ptrA->detectorE.refDistanceE >> 16 ) * scaleL ) >> 20; + uint32 logEyeDistL = bbs_intLog2( eyeDistL ); + int32 bbpL = 11 - logEyeDistL; + bbpL = bbpL < 0 ? 0 : bbpL; + bbpL = bbpL > 6 ? 6 : bbpL; + bts_IdCluster2D_copyTransform( cpA, idClusterPtrA, &ptrA->detectorE.refClusterE, altL, bbpL ); + } + + return ( actL + 0x10000000 ) >> 5; /*output range 0...1 in 8.24*/ +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_getFaceDCR( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ) +{ + int32 confL = bpi_BFFaceFinder_getFace( cpA, ptrA, indexA, &dcrPtrA->offsE, &dcrPtrA->mainClusterE ); + bts_IdCluster2D_copy( cpA, &dcrPtrA->sdkClusterE, &dcrPtrA->mainClusterE ); + dcrPtrA->confidenceE = confL; + dcrPtrA->approvedE = confL > ( ( int32 )1 << 23 ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_setMaxImageSize( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA ) +{ + ptrA->detectorE.maxImageWidthE = maxImageWidthA; + ptrA->detectorE.maxImageHeightE = maxImageHeightA; +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_setParams( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA ) +{ + bbs_DEF_fNameL( "bpi_BFFaceFinder_setParams" ); + + if( bbs_Context_error( cpA ) ) return; + + if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) + { + bbs_ERROR1( "%s:\nObject type mismatch", fNameL ); + return; + } + bpi_BFFaceFinder_setMaxImageSize( cpA, ( struct bpi_BFFaceFinder* )ptrA, maxImageWidthA, maxImageHeightA ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_setRange( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + uint32 minEyeDistanceA, + uint32 maxEyeDistanceA ) +{ + bbs_DEF_fNameL( "bpi_BFFaceFinder_setParams" ); + + if( bbs_Context_error( cpA ) ) return; + + if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) + { + bbs_ERROR1( "%s:\nObject type mismatch", fNameL ); + return; + } + bpi_BFFaceFinder_setMinEyeDistance( cpA, ( struct bpi_BFFaceFinder* )ptrA, minEyeDistanceA ); + bpi_BFFaceFinder_setMaxEyeDistance( cpA, ( struct bpi_BFFaceFinder* )ptrA, maxEyeDistanceA ); +} + +/* ------------------------------------------------------------------------- */ + +int32 bpi_BFFaceFinder_processDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + struct bpi_DCR* dcrPtrA ) +{ + bbs_DEF_fNameL( "bpi_BFFaceFinder_processDcr" ); + + if( bbs_Context_error( cpA ) ) return 0; + + if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) + { + bbs_ERROR1( "%s:\nObject type mismatch", fNameL ); + return 0; + } + + return bpi_BFFaceFinder_process( cpA, + ( const struct bpi_BFFaceFinder* )ptrA, + dcrPtrA->imageDataPtrE, + dcrPtrA->imageWidthE, + dcrPtrA->imageHeightE, + &dcrPtrA->roiRectE, + &dcrPtrA->offsE, + &dcrPtrA->mainClusterE ); +} + +/* ------------------------------------------------------------------------- */ + +int32 bpi_BFFaceFinder_putDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + struct bpi_DCR* dcrPtrA ) +{ + bbs_DEF_fNameL( "bpi_BFFaceFinder_putDcr" ); + + if( bbs_Context_error( cpA ) ) return 0; + + if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) + { + bbs_ERROR1( "%s:\nObject type mismatch", fNameL ); + return 0; + } + + return bpi_BFFaceFinder_multiProcess( cpA, + ( const struct bpi_BFFaceFinder* )ptrA, + dcrPtrA->imageDataPtrE, + dcrPtrA->imageWidthE, + dcrPtrA->imageHeightE, + &dcrPtrA->roiRectE ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_BFFaceFinder_getDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ) +{ + bbs_DEF_fNameL( "bpi_BFFaceFinder_getDcr" ); + + if( bbs_Context_error( cpA ) ) return; + + if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) + { + bbs_ERROR1( "%s:\nObject type mismatch", fNameL ); + return; + } + + bpi_BFFaceFinder_getFaceDCR( cpA, ( const struct bpi_BFFaceFinder* )ptrA, indexA, dcrPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_APIEm/BFFaceFinder.h b/Embedded/common/src/b_APIEm/BFFaceFinder.h new file mode 100644 index 0000000..3f1b438 --- /dev/null +++ b/Embedded/common/src/b_APIEm/BFFaceFinder.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bpi_BF_FACE_FINDER_EM_H +#define bpi_BF_FACE_FINDER_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_APIEm/FaceFinder.h" +#include "b_BitFeatureEm/ScanDetector.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bpi_DCR; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bpi_BF_FACE_FINDER_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** Face Finder using ractangle features */ +struct bpi_BFFaceFinder +{ + /* ---- private data --------------------------------------------------- */ + + /** base object */ + struct bpi_FaceFinder baseE; + + /* number of detected faces in last call of multiProcess in face data buffer */ + uint32 detectedFacesE; + + /* number of available faces in last call of multiProcess in face data buffer */ + uint32 availableFacesE; + + /* pointer to face data buffer */ + int32* faceDataBufferE; + + /* ---- public data ---------------------------------------------------- */ + + /* detector */ + struct bbf_ScanDetector detectorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes module */ +void bpi_BFFaceFinder_init( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA ); + +/** destroys module */ +void bpi_BFFaceFinder_exit( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copies module */ +void bpi_BFFaceFinder_copy( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + const struct bpi_BFFaceFinder* srcPtrA ); + +/** determines equality of parameters */ +flag bpi_BFFaceFinder_equal( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + const struct bpi_BFFaceFinder* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** minimum eye distance (pixel) */ +uint32 bpi_BFFaceFinder_getMinEyeDistance( const struct bpi_BFFaceFinder* ptrA ); + +/** maximum eye distance (pixel) */ +uint32 bpi_BFFaceFinder_getMaxEyeDistance( const struct bpi_BFFaceFinder* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** minimum eye distance (pixel) */ +void bpi_BFFaceFinder_setMinEyeDistance( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + uint32 distA ); + +/** maximum eye distance (pixel) */ +void bpi_BFFaceFinder_setMaxEyeDistance( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + uint32 distA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bpi_BFFaceFinder_memSize( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA ); + +/** writes object to memory; returns number of 16-bit words written */ +uint32 bpi_BFFaceFinder_memWrite( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of 16-bit words read + * Note: Before executing this function the maximum image dimensions must be specified + * through function bpi_BFFaceFinder_setMaxImageSize. This is to ensure proper allocation + * of internal memory. Otherwise this function will cause an exception. + */ +uint32 bpi_BFFaceFinder_memRead( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** processes image for single face detection; + * returns confidence ( 8.24 ) + * fills external id cluster with node positions and ids + * + * If roiPtrA is NULL, the whole image is considered for processsing + * otherwise *roiPtrA specifies a section of the original image to which + * processing is limited. All coordinates refer to that section and must + * eventually be adjusted externally. + * The roi rectangle must not include pixels outside of the original image + * (checked -> error). The rectangle may be of uneven width. + * + * offsPtrA points to an offset vector (whole pixels) that is to be added to + * cluster coordinates in order to obtain image coordinates + * + */ +int32 bpi_BFFaceFinder_process( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA, + struct bts_Int16Vec2D* offsPtrA, + struct bts_IdCluster2D* idClusterPtrA ); + +/** Processes integral image for multiple face detection; + * returns number of faces detected + * return pointer to faceBuffer (intermediate data format) + * call getFace() to retrieve face information from buffer. + * *faceDataBufferPtrA is set to the address of an internal buffer that is valid until the next image processing + * + * Positions are sorted by confidence (highest confidence first) + * + * When this function returns 0 (no face detected) faceDataBuffer + * still contains one valid entry retrievable by getFace() that + * represents the most likely position. The confidence is then below + * or equal 0.5. + * + * If roiPtrA is NULL, the whole image is considered for processsing + * otherwise *roiPtrA specifies a section of the original image to which + * processing is limited. All coordinates refer to that section and must + * eventually be adjusted externally. + * The roi rectangle must not include pixels outside of the original image + * (checked -> error). The rectangle may be of uneven width. + */ +uint32 bpi_BFFaceFinder_multiProcess( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA ); + +/** Extracts a single face from a face buffer that was previously filled with face data by function + * multiProcess(). + * returns confidence ( 8.24 ) + * Fills external id cluster with node positions and ids + * + * offsPtrA points to an offset vector (whole pixels) that is to be added to + * cluster coordinates in order to obtain image coordinates + */ +uint32 bpi_BFFaceFinder_getFace( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + uint32 indexA, + struct bts_Int16Vec2D* offsPtrA, + struct bts_IdCluster2D* idClusterPtrA ); + +/** Extracts a single face from a face buffer that was previously filled with face data by function + * multiProcess(). + * returns confidence ( 8.24 ) + * provides + * - id cluster with node positions and ids + * - confidence + */ +void bpi_BFFaceFinder_getFaceDCR( struct bbs_Context* cpA, + const struct bpi_BFFaceFinder* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ); + +/** this function must be executed before calling _memRead */ +void bpi_BFFaceFinder_setMaxImageSize( struct bbs_Context* cpA, + struct bpi_BFFaceFinder* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA ); + +/** initializes some parameters prior to reading + * Overload of vpSetParams + * wraps function setMaxImageSize + */ +void bpi_BFFaceFinder_setParams( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA ); + +/** sets detection range + * Overload of vpSetParams + */ +void bpi_BFFaceFinder_setRange( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + uint32 minEyeDistanceA, + uint32 maxEyeDistanceA ); + +/** Single face processing function; returns confidence (8.24) + * Overload of vpProcess + * wraps function process + */ +int32 bpi_BFFaceFinder_processDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + struct bpi_DCR* dcrPtrA ); + +/** Multiple face processing function; returns number of faces detected + * Overload of vpPutDcr + * wraps function multiProcess + */ +int32 bpi_BFFaceFinder_putDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + struct bpi_DCR* dcrPtrA ); + +/** Retrieves indexed face from face finder after calling PutDCR + * Overload of vpGetDcr + * wraps function getFaceDCR + */ +void bpi_BFFaceFinder_getDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ); + +#endif /* bpi_BF_FACE_FINDER_EM_H */ diff --git a/Embedded/common/src/b_APIEm/DCR.c b/Embedded/common/src/b_APIEm/DCR.c new file mode 100644 index 0000000..c1fc1f6 --- /dev/null +++ b/Embedded/common/src/b_APIEm/DCR.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_APIEm/DCR.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_DCR_init( struct bbs_Context* cpA, + struct bpi_DCR* ptrA ) +{ + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + ptrA->imageDataPtrE = NULL; + ptrA->imageWidthE = 0; + ptrA->imageHeightE = 0; + bts_Int16Vec2D_init( &ptrA->offsE ); + bts_IdCluster2D_init( cpA, &ptrA->mainClusterE ); + bts_IdCluster2D_init( cpA, &ptrA->sdkClusterE ); + ptrA->confidenceE = 0; + ptrA->approvedE = FALSE; + ptrA->idE = 0; + ptrA->roiRectE = bts_Int16Rect_create( 0, 0, 0, 0 ); + bbs_UInt16Arr_init( cpA, &ptrA->cueDataE ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_DCR_exit( struct bbs_Context* cpA, + struct bpi_DCR* ptrA ) +{ + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + ptrA->imageDataPtrE = NULL; + ptrA->imageWidthE = 0; + ptrA->imageHeightE = 0; + bts_Int16Vec2D_exit( &ptrA->offsE ); + bts_IdCluster2D_exit( cpA, &ptrA->mainClusterE ); + bts_IdCluster2D_exit( cpA, &ptrA->sdkClusterE ); + ptrA->confidenceE = 0; + ptrA->approvedE = FALSE; + ptrA->idE = 0; + bbs_UInt16Arr_exit( cpA, &ptrA->cueDataE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_DCR_create( struct bbs_Context* cpA, + struct bpi_DCR* ptrA, + uint32 imageWidthA, + uint32 imageHeightA, + uint32 cueSizeA, + struct bbs_MemTbl* mtpA ) +{ + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = + bbs_MemTbl_fastestSegPtr( cpA, &memTblL, + bpi_DCR_MAX_CLUSTER_SIZE * bbs_SIZEOF16( struct bts_Int16Vec2D ) ); + if( bbs_Context_error( cpA ) ) return; + + bts_IdCluster2D_create( cpA, &ptrA->mainClusterE, bpi_DCR_MAX_CLUSTER_SIZE, espL ); + bts_IdCluster2D_size( cpA, &ptrA->mainClusterE, 0 ); + if( bbs_Context_error( cpA ) ) return; + bts_IdCluster2D_create( cpA, &ptrA->sdkClusterE, bpi_DCR_MAX_SDK_CLUSTER_SIZE, espL ); + bts_IdCluster2D_size( cpA, &ptrA->sdkClusterE, 0 ); + if( bbs_Context_error( cpA ) ) return; + if( bbs_Context_error( cpA ) ) return; + bbs_UInt16Arr_create( cpA, &ptrA->cueDataE, cueSizeA, espL ); + bbs_UInt16Arr_size( cpA, &ptrA->cueDataE, 0 ); + + ptrA->maxImageWidthE = imageWidthA; + ptrA->maxImageHeightE = imageHeightA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_DCR_assignGrayByteImage( struct bbs_Context* cpA, + struct bpi_DCR* ptrA, + const void* bufferPtrA, + uint32 widthA, + uint32 heightA ) +{ + bbs_DEF_fNameL( "void bpi_DCR_assignGrayByteImage( struct bbs_Context* cpA, struct bpi_DCR* ptrA, const void* bufferPtrA, uint32 widthA, uint32 heightA )" ) + + if( widthA > ptrA->maxImageWidthE || heightA > ptrA->maxImageHeightE ) + { + bbs_ERROR5( "%s:\nSize of assigned image (%ix%i) exceeds maximum size defined at DCR initialization (%ix%i).", + fNameL, + widthA, heightA, + ptrA->maxImageWidthE, ptrA->maxImageHeightE ); + return; + } + + if( ( widthA & 1 ) != 0 ) + { + bbs_ERROR1( "%s:\nWidth of image must be even.\n", fNameL ); + return; + } + + ptrA->imageDataPtrE = ( void* )bufferPtrA; + ptrA->imageWidthE = widthA; + ptrA->imageHeightE = heightA; + + /* reset some data */ + ptrA->roiRectE = bts_Int16Rect_create( 0, 0, widthA, heightA ); + bts_IdCluster2D_size( cpA, &ptrA->mainClusterE, 0 ); + bts_IdCluster2D_size( cpA, &ptrA->sdkClusterE, 0 ); + bbs_UInt16Arr_size( cpA, &ptrA->cueDataE, 0 ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_DCR_assignGrayByteImageROI( struct bbs_Context* cpA, + struct bpi_DCR* ptrA, + const void* bufferPtrA, + uint32 widthA, + uint32 heightA, + const struct bts_Int16Rect* pRectA ) +{ + bbs_DEF_fNameL( "void bpi_DCR_assignGrayByteImageROI( struct bpi_DCR* ptrA, const void* bufferPtrA, uint32 widthA, uint32 heightA )" ) + + if( widthA > ptrA->maxImageWidthE || heightA > ptrA->maxImageHeightE ) + { + bbs_ERROR5( "%s:\nSize of assigned image (%ix%i) exceeds maximum size defined at DCR initialization (%ix%i).", + fNameL, + widthA, heightA, + ptrA->maxImageWidthE, ptrA->maxImageHeightE ); + return; + } + + if( ( widthA & 1 ) != 0 ) + { + bbs_ERROR1( "%s:\nWidth of image must be even.\n", + fNameL ); + return; + } + + if( pRectA->x2E < pRectA->x1E || pRectA->y2E < pRectA->y1E || + pRectA->x1E < 0 || pRectA->y1E < 0 || + pRectA->x2E > ( int32 )widthA || pRectA->y2E > ( int32 )heightA ) + { + bbs_ERROR1( "%s:\nInvalid ROI rectangle.\n", fNameL ); + return; + } + + ptrA->imageDataPtrE = ( void* )bufferPtrA; + ptrA->imageWidthE = widthA; + ptrA->imageHeightE = heightA; + + /* reset some data */ + ptrA->roiRectE = *pRectA; + bts_IdCluster2D_size( cpA, &ptrA->mainClusterE, 0 ); + bts_IdCluster2D_size( cpA, &ptrA->sdkClusterE, 0 ); + bbs_UInt16Arr_size( cpA, &ptrA->cueDataE, 0 ); +} + +/* ------------------------------------------------------------------------- */ + +int32 bpi_DCR_confidence( struct bbs_Context* cpA, + const struct bpi_DCR* ptrA ) +{ + return ptrA->confidenceE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_APIEm/DCR.h b/Embedded/common/src/b_APIEm/DCR.h new file mode 100644 index 0000000..64b2378 --- /dev/null +++ b/Embedded/common/src/b_APIEm/DCR.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bpi_DCR_EM_H +#define bpi_DCR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemTbl.h" +#include "b_ImageEm/UInt16ByteImage.h" +#include "b_ImageEm/UInt32Image.h" +#include "b_TensorEm/IdCluster2D.h" +#include "b_TensorEm/RBFMap2D.h" +#include "b_BitFeatureEm/Scanner.h" + + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** maximum size of dcr cluster */ +#define bpi_DCR_MAX_CLUSTER_SIZE 60 + +/** maximum size of dcr sdk cluster */ +#define bpi_DCR_MAX_SDK_CLUSTER_SIZE 24 + +/* ---- object definition -------------------------------------------------- */ + +/** data carrier */ +struct bpi_DCR +{ + /* ---- temporary data ------------------------------------------------- */ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** maximum allowed image width */ + uint32 maxImageWidthE; + + /** maximum allowed image height */ + uint32 maxImageHeightE; + + /** pointer to original image data */ + void* imageDataPtrE; + + /** width of original image */ + uint32 imageWidthE; + + /** height of original image */ + uint32 imageHeightE; + + /** offset refering to main and sdk clusters */ + struct bts_Int16Vec2D offsE; + + /** main cluster */ + struct bts_IdCluster2D mainClusterE; + + /** output cluster accessible by sdk users */ + struct bts_IdCluster2D sdkClusterE; + + /** confidence value ( 8.24 ) */ + int32 confidenceE; + + /** approval flag */ + flag approvedE; + + /** (image) id value */ + int32 idE; + + /** region of interest */ + struct bts_Int16Rect roiRectE; + + /** cue data */ + struct bbs_UInt16Arr cueDataE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes data carrier */ +void bpi_DCR_init( struct bbs_Context* cpA, + struct bpi_DCR* ptrA ); + +/** destroys data carrier */ +void bpi_DCR_exit( struct bbs_Context* cpA, + struct bpi_DCR* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** create a data carrier */ +void bpi_DCR_create( struct bbs_Context* cpA, + struct bpi_DCR* ptrA, + uint32 imageWidthA, + uint32 imageHeightA, + uint32 cueSizeA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** references external byte gray image through memory block referenced by bufferPtrA to be used as input image */ +void bpi_DCR_assignGrayByteImage( struct bbs_Context* cpA, + struct bpi_DCR* ptrA, + const void* bufferPtrA, + uint32 widthA, + uint32 heightA ); + +/** assigns external byte gray image as input image and region of interest. + * + * bufferPtrA: pointer to memory block of imput image + * pRectA: rectangle describing region of interest + */ +void bpi_DCR_assignGrayByteImageROI( struct bbs_Context* cpA, + struct bpi_DCR* ptrA, + const void* bufferPtrA, + uint32 widthA, + uint32 heightA, + const struct bts_Int16Rect* pRectA ); + +/** returns confidence 8.24 fixed format */ +int32 bpi_DCR_confidence( struct bbs_Context* cpA, + const struct bpi_DCR* ptrA ); + +#endif /* bpi_DCR_EM_H */ diff --git a/Embedded/common/src/b_APIEm/FaceFinder.c b/Embedded/common/src/b_APIEm/FaceFinder.c new file mode 100644 index 0000000..d12c04d --- /dev/null +++ b/Embedded/common/src/b_APIEm/FaceFinder.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_APIEm/FaceFinder.h" +#include "b_APIEm/BFFaceFinder.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinder_init( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA ) +{ + ptrA->typeE = 0; + ptrA->vpSetParamsE = NULL; + ptrA->vpSetRangeE = NULL; + ptrA->vpProcessE = NULL; + ptrA->vpPutDcrE = NULL; + ptrA->vpGetDcrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinder_exit( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA ) +{ + ptrA->typeE = 0; + ptrA->vpSetParamsE = NULL; + ptrA->vpSetRangeE = NULL; + ptrA->vpProcessE = NULL; + ptrA->vpPutDcrE = NULL; + ptrA->vpGetDcrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinder_copy( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + const struct bpi_FaceFinder* srcPtrA ) +{ + ptrA->typeE = srcPtrA->typeE; + ptrA->vpSetParamsE = srcPtrA->vpSetParamsE; + ptrA->vpSetRangeE = srcPtrA->vpSetRangeE; + ptrA->vpProcessE = srcPtrA->vpProcessE; + ptrA->vpPutDcrE = srcPtrA->vpPutDcrE; + ptrA->vpGetDcrE = srcPtrA->vpGetDcrE; +} + +/* ------------------------------------------------------------------------- */ + +flag bpi_FaceFinder_equal( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + const struct bpi_FaceFinder* srcPtrA ) +{ + + if( ptrA->typeE != srcPtrA->typeE ) return FALSE; + if( ptrA->vpSetParamsE != srcPtrA->vpSetParamsE ) return FALSE; + if( ptrA->vpSetRangeE != srcPtrA->vpSetRangeE ) return FALSE; + if( ptrA->vpProcessE != srcPtrA->vpProcessE ) return FALSE; + if( ptrA->vpPutDcrE != srcPtrA->vpPutDcrE ) return FALSE; + if( ptrA->vpGetDcrE != srcPtrA->vpGetDcrE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_FaceFinder_memSize( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA ) +{ + uint32 memSizeL = 0; + memSizeL += bbs_SIZEOF16( ptrA->typeE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_FaceFinder_memWrite( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bpi_FaceFinder_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &ptrA->typeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_FaceFinder_memRead( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + const uint16* memPtrA ) +{ + bbs_DEF_fNameL( "uint32 bpi_FaceFinder_memRead( struct bbs_Context* cpA, struct bpi_FaceFinder* ptrA, const uint16* memPtrA )" ) + uint32 typeL; + + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &typeL, memPtrA ); + + if( typeL != ptrA->typeE ) + { + bbs_ERROR1( "%s:\nObject type mismatch! Attempt to read an incorrect object.", fNameL ); + return 0; + } + + return bpi_FaceFinder_memSize( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_faceFinderInit( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + enum bpi_FaceFinderType typeA ) +{ + switch( typeA ) + { + case bpi_FF_BF_FACE_FINDER: bpi_BFFaceFinder_init( cpA, ( struct bpi_BFFaceFinder* )ptrA ); return; + + default: bbs_ERROR0( "bpi_faceFinderInit: invalid type" ); + } +} + +/* ------------------------------------------------------------------------- */ + +void bpi_faceFinderExit( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA ) +{ + switch( ptrA->typeE ) + { + case bpi_FF_BF_FACE_FINDER: bpi_BFFaceFinder_exit( cpA, ( struct bpi_BFFaceFinder* )ptrA ); return; + + default: bbs_ERROR0( "bpi_faceFinderExit: invalid type" ); + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_faceFinderMemSize( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA ) +{ + switch( ptrA->typeE ) + { + case bpi_FF_BF_FACE_FINDER: return bpi_BFFaceFinder_memSize( cpA, ( struct bpi_BFFaceFinder* )ptrA ); + + default: bbs_ERROR0( "bpi_faceFinderExit: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_faceFinderMemWrite( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, uint16* memPtrA ) +{ + switch( ptrA->typeE ) + { + case bpi_FF_BF_FACE_FINDER: return bpi_BFFaceFinder_memWrite( cpA, ( struct bpi_BFFaceFinder* )ptrA, memPtrA ); + + default: bbs_ERROR0( "bpi_faceFinderMemWrite: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_faceFinderMemRead( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + switch( ptrA->typeE ) + { + case bpi_FF_BF_FACE_FINDER: return bpi_BFFaceFinder_memRead( cpA, ( struct bpi_BFFaceFinder* )ptrA, memPtrA, mtpA ); + + default: bbs_ERROR0( "bpi_faceFinderMemRead: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_faceFinderSizeOf16( struct bbs_Context* cpA, enum bpi_FaceFinderType typeA ) +{ + switch( typeA ) + { + case bpi_FF_BF_FACE_FINDER: return bbs_SIZEOF16( struct bpi_BFFaceFinder ); + + default: bbs_ERROR0( "bpi_faceFinderSizeOf16: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_APIEm/FaceFinder.h b/Embedded/common/src/b_APIEm/FaceFinder.h new file mode 100644 index 0000000..76c4829 --- /dev/null +++ b/Embedded/common/src/b_APIEm/FaceFinder.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bpi_FACE_FINDER_EM_H +#define bpi_FACE_FINDER_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/Flt16Vec.h" +#include "b_TensorEm/IdCluster2D.h" +#include "b_APIEm/DCR.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** Object Type */ +enum bpi_FaceFinderType +{ + bpi_FF_UNDEFINED = 0, + bpi_FF_BF_FACE_FINDER /* bitfeature based faceFinder */ +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** base object for face finder modules (occurs as first element in all face finder objects) */ +struct bpi_FaceFinder +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** object type */ + uint32 typeE; + + /* ---- virtual functions ---------------------------------------------- */ + + /** initializes some parameters prior to reading */ + void ( *vpSetParamsE )( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA ); + + /** sets detection range */ + void ( *vpSetRangeE )( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + uint32 minEyeDistanceA, + uint32 maxEyeDistanceA ); + + /** single face processing function; returns confidence (8.24) */ + int32 ( *vpProcessE )( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + struct bpi_DCR* dcrPtrA ); + + /** multiple face processing function; returns number of faces detected */ + int32 ( *vpPutDcrE )( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + struct bpi_DCR* dcrPtrA ); + + /** retrieves indexed face from face finder after calling PutDCR */ + void ( *vpGetDcrE )( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ); + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bpi_FaceFinder */ +void bpi_FaceFinder_init( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA ); + +/** resets bpi_FaceFinder */ +void bpi_FaceFinder_exit( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bpi_FaceFinder_copy( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + const struct bpi_FaceFinder* srcPtrA ); + +/** equal operator */ +flag bpi_FaceFinder_equal( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + const struct bpi_FaceFinder* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bpi_FaceFinder_memSize( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bpi_FaceFinder_memWrite( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bpi_FaceFinder_memRead( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** virtual init function */ +void bpi_faceFinderInit( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + enum bpi_FaceFinderType typeA ); + +/** virtual exit function */ +void bpi_faceFinderExit( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA ); + +/** virtual mem size function */ +uint32 bpi_faceFinderMemSize( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA ); + +/** virtual mem write function */ +uint32 bpi_faceFinderMemWrite( struct bbs_Context* cpA, + const struct bpi_FaceFinder* ptrA, + uint16* memPtrA ); + +/** virtual mem read function */ +uint32 bpi_faceFinderMemRead( struct bbs_Context* cpA, + struct bpi_FaceFinder* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/** virtual sizeof operator for 16bit units */ +uint32 bpi_faceFinderSizeOf16( struct bbs_Context* cpA, + enum bpi_FaceFinderType typeA ); + +#endif /* bpi_FACE_FINDER_EM_H */ + diff --git a/Embedded/common/src/b_APIEm/FaceFinderRef.c b/Embedded/common/src/b_APIEm/FaceFinderRef.c new file mode 100644 index 0000000..01e5ed1 --- /dev/null +++ b/Embedded/common/src/b_APIEm/FaceFinderRef.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_APIEm/FaceFinderRef.h" +#include "b_APIEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinderRef_init( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA ) +{ + bbs_UInt16Arr_init( cpA, &ptrA->objBufE ); + ptrA->faceFinderPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinderRef_exit( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA ) +{ + if( ptrA->faceFinderPtrE != NULL ) bpi_faceFinderExit( cpA, ptrA->faceFinderPtrE ); + bbs_UInt16Arr_exit( cpA, &ptrA->objBufE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinderRef_copy( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + const struct bpi_FaceFinderRef* srcPtrA ) +{ + bbs_ERROR0( "bpi_FaceFinderRef_copy: function is not implemented" ); +} + +/* ------------------------------------------------------------------------- */ + +flag bpi_FaceFinderRef_equal( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + const struct bpi_FaceFinderRef* srcPtrA ) +{ + bbs_ERROR0( "bpi_FaceFinderRef_equal: function is not implemented" ); + return FALSE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_FaceFinderRef_memSize( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA ) +{ + uint32 memSizeL = 0; + memSizeL += bbs_SIZEOF16( uint32 ); /* mem size */ + memSizeL += bbs_SIZEOF16( flag ); /* object presence flag */ + if( ptrA->faceFinderPtrE != NULL ) memSizeL += bpi_faceFinderMemSize( cpA, ptrA->faceFinderPtrE ); + memSizeL += bbs_SIZEOF16( uint16 ); /* csa */ + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_FaceFinderRef_memWrite( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bpi_FaceFinderRef_memSize( cpA, ptrA ); + flag objPresentL = ptrA->faceFinderPtrE != NULL; + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &objPresentL, memPtrA ); + if( objPresentL ) memPtrA += bpi_faceFinderMemWrite( cpA, ptrA->faceFinderPtrE, memPtrA ); + memPtrA += bpi_memWriteCsa16( memPtrA, memSizeL, 0xFFFF ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_FaceFinderRef_memRead( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL; + flag objPresentL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &objPresentL, memPtrA ); + + /* check object & allocate data buffer */ + { + const uint16* memPtrL = memPtrA; + uint32 dataSizeL = 0; + + if( objPresentL ) + { + enum bpi_FaceFinderType typeL = ( enum bpi_FaceFinderType )bbs_memPeek32( memPtrL + 4 ); + dataSizeL += bpi_faceFinderSizeOf16( cpA, typeL ); + memPtrL += bbs_memPeek32( memPtrL ); + } + + bbs_UInt16Arr_create( cpA, &ptrA->objBufE, dataSizeL, espL ); + } + + /* load object */ + { + uint16* dataPtrL = ptrA->objBufE.arrPtrE; + + if( objPresentL ) + { + enum bpi_FaceFinderType typeL = ( enum bpi_FaceFinderType )bbs_memPeek32( memPtrA + 4 ); + ptrA->faceFinderPtrE = ( struct bpi_FaceFinder* )dataPtrL; + bpi_faceFinderInit( cpA, ptrA->faceFinderPtrE, typeL ); + ptrA->faceFinderPtrE->vpSetParamsE( cpA, ptrA->faceFinderPtrE, maxImageWidthA, maxImageHeightA ); + memPtrA += bpi_faceFinderMemRead( cpA, ptrA->faceFinderPtrE, memPtrA, &memTblL ); + dataPtrL += bpi_faceFinderSizeOf16( cpA, typeL ); + } + else + { + ptrA->faceFinderPtrE = NULL; + } + } + + memPtrA += bpi_memReadCsa16( memPtrA ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinderRef_setParams( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA ) +{ + bbs_DEF_fNameL( "bpi_FaceFinderRef_setParams" ); + if( ptrA->faceFinderPtrE == NULL ) + { + bbs_ERROR1( "%s:\nNo face finder object was loaded", fNameL ); + return; + } + ptrA->faceFinderPtrE->vpSetParamsE( cpA, ptrA->faceFinderPtrE, maxImageWidthA, maxImageHeightA ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinderRef_setRange( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + uint32 minEyeDistanceA, + uint32 maxEyeDistanceA ) +{ + bbs_DEF_fNameL( "bpi_FaceFinderRef_setRange" ); + if( ptrA->faceFinderPtrE == NULL ) + { + bbs_ERROR1( "%s:\nNo face finder object was loaded", fNameL ); + return; + } + ptrA->faceFinderPtrE->vpSetRangeE( cpA, ptrA->faceFinderPtrE, minEyeDistanceA, maxEyeDistanceA ); +} + +/* ------------------------------------------------------------------------- */ + +int32 bpi_FaceFinderRef_process( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + struct bpi_DCR* dcrPtrA ) +{ + bbs_DEF_fNameL( "bpi_FaceFinderRef_process" ); + if( ptrA->faceFinderPtrE == NULL ) + { + bbs_ERROR1( "%s:\nNo face finder object was loaded", fNameL ); + return 0; + } + return ptrA->faceFinderPtrE->vpProcessE( cpA, ptrA->faceFinderPtrE, dcrPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +int32 bpi_FaceFinderRef_putDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + struct bpi_DCR* dcrPtrA ) +{ + bbs_DEF_fNameL( "bpi_FaceFinderRef_putDcr" ); + if( ptrA->faceFinderPtrE == NULL ) + { + bbs_ERROR1( "%s:\nNo face finder object was loaded", fNameL ); + return 0; + } + return ptrA->faceFinderPtrE->vpPutDcrE( cpA, ptrA->faceFinderPtrE, dcrPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +void bpi_FaceFinderRef_getDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ) +{ + bbs_DEF_fNameL( "bpi_FaceFinderRef_getDcr" ); + if( ptrA->faceFinderPtrE == NULL ) + { + bbs_ERROR1( "%s:\nNo face finder object was loaded", fNameL ); + return; + } + ptrA->faceFinderPtrE->vpGetDcrE( cpA, ptrA->faceFinderPtrE, indexA, dcrPtrA ); +} + + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_APIEm/FaceFinderRef.h b/Embedded/common/src/b_APIEm/FaceFinderRef.h new file mode 100644 index 0000000..4fcfe09 --- /dev/null +++ b/Embedded/common/src/b_APIEm/FaceFinderRef.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bpi_FACE_FINDER_REF_EM_H +#define bpi_FACE_FINDER_REF_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/UInt16Arr.h" +#include "b_APIEm/FaceFinder.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** type independent reference to a faceFinder module */ +struct bpi_FaceFinderRef +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** object buffer */ + struct bbs_UInt16Arr objBufE; + + /** faceFinder pointer */ + struct bpi_FaceFinder* faceFinderPtrE; + + /* ---- functions ------------------------------------------------------ */ + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bpi_FaceFinderRef */ +void bpi_FaceFinderRef_init( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA ); + +/** resets bpi_FaceFinderRef */ +void bpi_FaceFinderRef_exit( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bpi_FaceFinderRef_copy( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + const struct bpi_FaceFinderRef* srcPtrA ); + +/** equal operator */ +flag bpi_FaceFinderRef_equal( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + const struct bpi_FaceFinderRef* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bpi_FaceFinderRef_memSize( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bpi_FaceFinderRef_memWrite( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bpi_FaceFinderRef_memRead( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + uint32 maxImageWidthA, + uint32 maxImageHeightA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets detection range */ +void bpi_FaceFinderRef_setRange( struct bbs_Context* cpA, + struct bpi_FaceFinderRef* ptrA, + uint32 minEyeDistanceA, + uint32 maxEyeDistanceA ); + +/** single face processing function; returns confidence (8.24) */ +int32 bpi_FaceFinderRef_process( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + struct bpi_DCR* dcrPtrA ); + +/** multiple face processing function; returns number of faces detected */ +int32 bpi_FaceFinderRef_putDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + struct bpi_DCR* dcrPtrA ); + +/** retrieves indexed face from face finder after calling PutDCR */ +void bpi_FaceFinderRef_getDcr( struct bbs_Context* cpA, + const struct bpi_FaceFinderRef* ptrA, + uint32 indexA, + struct bpi_DCR* dcrPtrA ); + +#endif /* bpi_FACE_FINDER_REF_EM_H */ + diff --git a/Embedded/common/src/b_APIEm/Functions.c b/Embedded/common/src/b_APIEm/Functions.c new file mode 100644 index 0000000..fe8de17 --- /dev/null +++ b/Embedded/common/src/b_APIEm/Functions.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_APIEm/Functions.h" +#include "b_BasicEm/Memory.h" + + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bpi_normalizeSimilarities( struct bbs_Context* cpA, + const int32* rawSimArrA, + const int32* rawIdArrA, + uint32 rawSizeA, + const int32* refSimArrA, + const int32* refIdArrA, + uint32 refSizeA, + enum bpi_SimType simTypeA, + int32* outSimArrA ) +{ + /* 8.24 */ + int32 refSimL = 0; + uint32 iL, jL, kL; + int32* outPtrL = outSimArrA; + const int32* rawPtrL = rawSimArrA; + + switch( simTypeA ) + { + case bpi_RAW_SIM: + { + /* nothing to do */ + } + break; + + case bpi_SUB_MEAN: + { + int32 shiftL = 0; + int32 roundL = 0; + refSimL = 0; + for( iL = 0; iL < refSizeA; iL++ ) + { + refSimL += ( refSimArrA[ iL ] + roundL ) >> shiftL; + if( refSimL > 0x40000000 ) + { + refSimL = ( refSimL + 1 ) >> 1; + shiftL++; + roundL = ( int32 )1 << ( shiftL - 1 ); + } + } + refSimL = ( refSimL / refSizeA ) << shiftL; + } + break; + + case bpi_SUB_MAX_2: + { + int32 maxL = 0; + uint32 maxIndexL = 0; + int32 idL = 0; + + /* find raw maximum */ + for( iL = 0; iL < rawSizeA; iL++ ) + { + if( maxL < rawSimArrA[ iL ] ) + { + maxL = refSimArrA[ iL ]; + maxIndexL = iL; + } + } + + /* consider id of maximum equal to probe id */ + idL = rawIdArrA[ maxIndexL ]; + + /* find maximum similarity in ref array of different id */ + for( iL = 0; iL < refSizeA; iL++ ) + { + if( refIdArrA[ iL ] != idL ) + { + refSimL = ( refSimL > refSimArrA[ iL ] ) ? refSimL : refSimArrA[ iL ]; + } + } + } + break; + + case bpi_SUB_16_MAX_2: + { + int32 maxL = 0; + uint32 maxIndexL = 0; + int32 idL = 0; + + int32 maxSimArrL[ 16 ]; + bbs_memset32( maxSimArrL, ( uint32 )-1, bbs_SIZEOF32( maxSimArrL ) ); + + /* find raw maximum */ + for( iL = 0; iL < rawSizeA; iL++ ) + { + if( maxL < rawSimArrA[ iL ] ) + { + maxL = rawSimArrA[ iL ]; + maxIndexL = iL; + } + } + + /* consider id of maximum equal to probe id */ + idL = rawIdArrA[ maxIndexL ]; + + /* find 16 maximum similarities of different id in ref array */ + for( iL = 0; iL < refSizeA; iL++ ) + { + if( refIdArrA[ iL ] != idL ) + { + int32 simL = refSimArrA[ iL ]; + for( jL = 0; jL < 16; jL++ ) + { + if( simL > maxSimArrL[ jL ] ) break; + } + for( kL = 15; kL > jL; kL-- ) + { + maxSimArrL[ kL ] = maxSimArrL[ kL - 1 ]; + } + if( jL < 16 ) maxSimArrL[ jL ] = simL; + } + } + + refSimL = 0; + for( jL = 0; jL < 16; jL++ ) + { + if( maxSimArrL[ jL ] == -1 ) break; + refSimL += maxSimArrL[ jL ]; + } + + if( jL > 0 ) + { + refSimL /= jL; + } + } + break; + + default: + { + bbs_ERROR1( "void bpi_Identifier_normalizeSimilarities(): simTypeA '%i' is handled", simTypeA ); + return; + } + } + + /* refSimL -= 1.0 */ + refSimL -= ( (uint32)1 << 24 ); + + for( iL = rawSizeA; iL > 0; iL-- ) + { + *outPtrL++ = ( *rawPtrL++ - refSimL + 1 ) >> 1; + } + +} + +/* ------------------------------------------------------------------------- */ + +int32 bpi_normalizedSimilarity( struct bbs_Context* cpA, + int32 rawSimA, + int32 rawIdA, + const int32* refSimArrA, + const int32* refIdArrA, + uint32 refSizeA, + enum bpi_SimType simTypeA ) +{ + /* 8.24 */ + int32 refSimL = 0; + uint32 iL, jL, kL; + + switch( simTypeA ) + { + case bpi_RAW_SIM: + { + /* nothing to do */ + return rawSimA; /* return without adjustment of value range */ + } + + case bpi_SUB_MEAN: + { + int32 shiftL = 0; + int32 roundL = 0; + refSimL = 0; + for( iL = 0; iL < refSizeA; iL++ ) + { + refSimL += ( refSimArrA[ iL ] + roundL ) >> shiftL; + if( refSimL > 0x40000000 ) + { + refSimL = ( refSimL + 1 ) >> 1; + shiftL++; + roundL = ( int32 )1 << ( shiftL - 1 ); + } + } + refSimL = ( refSimL / refSizeA ) << shiftL; + } + break; + + case bpi_SUB_MAX_2: + { + /* find maximum similarity in ref array of different rawIdA */ + for( iL = 0; iL < refSizeA; iL++ ) + { + if( refIdArrA[ iL ] != rawIdA ) + { + refSimL = ( refSimL > refSimArrA[ iL ] ) ? refSimL : refSimArrA[ iL ]; + } + } + } + break; + + case bpi_SUB_16_MAX_2: + { + int32 maxSimArrL[ 16 ]; + int32 idL = rawIdA; + bbs_memset32( maxSimArrL, ( uint32 )-1, bbs_SIZEOF32( maxSimArrL ) ); + + /* find 16 maximum similarities of different id in ref array */ + for( iL = 0; iL < refSizeA; iL++ ) + { + if( refIdArrA[ iL ] != idL ) + { + int32 simL = refSimArrA[ iL ]; + for( jL = 0; jL < 16; jL++ ) + { + if( simL > maxSimArrL[ jL ] ) break; + } + for( kL = 15; kL > jL; kL-- ) + { + maxSimArrL[ kL ] = maxSimArrL[ kL - 1 ]; + } + if( jL < 16 ) maxSimArrL[ jL ] = simL; + } + } + + refSimL = 0; + for( jL = 0; jL < 16; jL++ ) + { + if( maxSimArrL[ jL ] == -1 ) break; + refSimL += maxSimArrL[ jL ]; + } + + if( jL > 0 ) + { + refSimL /= jL; + } + } + break; + + default: + { + bbs_ERROR1( "void bpi_Identifier_normalizeSimilarities(): simTypeA '%i' is handled", simTypeA ); + } + break; + } + + /* refSimL -= 1.0 */ + refSimL -= ( (uint32)1 << 24 ); + return ( rawSimA - refSimL + 1 ) >> 1; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_memWriteCsa16( uint16* memPtrA, uint32 memSizeA, uint16 chkSumA ) +{ + uint16* memPtrL = memPtrA - memSizeA + 1; + uint32 iL; + uint16 sumL = 0; + uint16 csaL = 0; + + bbs_memWrite16( &csaL, memPtrA ); + for( iL = 0; iL < memSizeA; iL++ ) + { + uint16 valL = 0; + memPtrL += bbs_memRead16( &valL, memPtrL ); + sumL += valL; + } + csaL = chkSumA - sumL; + + return bbs_memWrite16( &csaL, memPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bpi_memReadCsa16( const uint16* memPtrA ) +{ + return bbs_SIZEOF16( uint16 ); +} + +/* ------------------------------------------------------------------------- */ + diff --git a/Embedded/common/src/b_APIEm/Functions.h b/Embedded/common/src/b_APIEm/Functions.h new file mode 100644 index 0000000..f2f81bf --- /dev/null +++ b/Embedded/common/src/b_APIEm/Functions.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bpi_FUNCTIONS_EM_H +#define bpi_FUNCTIONS_EM_H + +/** + * This files contains general purpose functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + + +/** methods of similarty normalization for identification and verification */ +enum bpi_SimType +{ + bpi_RAW_SIM, /* take raw similarity only */ + bpi_SUB_MEAN, /* subtract average */ + bpi_SUB_MAX_1, /* subtract maximum (different id of each entry) */ + bpi_SUB_MAX_2, /* subtract maximum (different id of best entry) */ + bpi_SUB_4_MAX_2, /* subtract average maximum of best 4 entries (method 2) */ + bpi_SUB_8_MAX_2, /* subtract average maximum of best 8 entries (method 2) */ + bpi_SUB_16_MAX_2, /* subtract average maximum of best 16 entries (method 2) */ + bpi_SUB_32_MAX_2 /* subtract average maximum of best 32 entries (method 2) */ +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** Normalizes similarities. + * This function is used by identifier module + */ +void bpi_normalizeSimilarities( struct bbs_Context* cpA, + const int32* rawSimArrA, + const int32* rawIdArrA, + uint32 rawSizeA, + const int32* refSimArrA, + const int32* refIdArrA, + uint32 refSizeA, + enum bpi_SimType simTypeA, + int32* outSimArrA ); + +/** Returnes normalized single similarity. + * This function is used by verifier module + */ +int32 bpi_normalizedSimilarity( struct bbs_Context* cpA, + int32 rawSimA, + int32 rawIdA, + const int32* refSimArrA, + const int32* refIdArrA, + uint32 refSizeA, + enum bpi_SimType simTypeA ); + + + +/** writes checksum adjustment value to meet chkSumA to memory + * the function assumes that memPtrA is memSizeA - 1 units + * away from beginning of object-memory block + */ +uint32 bpi_memWriteCsa16( uint16* memPtrA, uint32 memSizeA, uint16 chkSumA ); + +/** takes checksum adjustment value from memory stream */ +uint32 bpi_memReadCsa16( const uint16* memPtrA ); + +/** tests check sum and produxes error condition if no match */ +void bpi_testCheckSum( struct bbs_Context* cpA, uint16* memPtrA, uint16 chkSumA, const char* fNameA ); + + +#endif /* bpi_FUNCTIONS_EM_H */ + diff --git a/Embedded/common/src/b_APIEm/Types.h b/Embedded/common/src/b_APIEm/Types.h new file mode 100644 index 0000000..ea2e294 --- /dev/null +++ b/Embedded/common/src/b_APIEm/Types.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bpi_TYPES_EM_H +#define bpi_TYPES_EM_H + +/** + * This file contains gerenral purpose types. + */ + +/* ---- includes ----------------------------------------------------------- */ + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** Type of module */ +enum bpi_ModuleType +{ + bpi_UNDEFINED, + bpi_OLD_FACE_FINDER_REMOVED, + bpi_FACE_FINDER, + bpi_LANDMARKER, + bpi_CONVERTER, + bpi_IDENTIFIER +}; + +/** List of object identifiers + * This list is is synchronized with enum list epi_ObjectId + * Not all types are neccessarily in use in the embedded realm + * values in round braces ( e.g. (32) ) denote the size in bits of the associated data type + * + * Object formats: + * ASCII String: 0-terminates string of characters + * + * Image: <(32) type><(32) width><(32) height><(8) byte1><(8) byte2>.... + * type: 0: gray image - pixels are bytes starting at upper left corner + * 1: rgb color images - prixels are 3-byte rgb groups starting at upper left corner + * 2: jpeg compressed image (<(32) type><(32) width><(32) height> precede jpeg data) + * + * Cue: SDK compatible template (bpi_IdCueHdr + subsequent data) + * + * The type values never change. Type numbers can be taken for granted. + */ +enum bpi_ObjectId +{ + bpi_ID_FILE, /** (ASCII String) file name (of image) */ + bpi_ID_BOUNDING_BOX, /** bounding box (coordinates of original image) */ + bpi_ID_GRAPH, /** ground truth graph */ + bpi_ID_FILE_LIST, /** list of filenames */ + bpi_ID_GRAPH_LIST, /** list of egp_SpatialGraph (multiple ground truth graphs per image) */ + bpi_ID_GROUP, /** generic group element (used in the embedded domain to identify an object set) */ + bpi_ID_IMAGE = 256, /** (Image) downscaled byte image */ + bpi_ID_IMAGE_FRAME, /** bounding box surrounding original image */ + bpi_ID_IMAGE_ID, /** (32)-integer id number of person por object in image */ + bpi_ID_SIGNATURE_NAME = 512, /** (ASCII String) name of gallery element (=signature) */ + bpi_ID_CONFIDENCE, /** general purpose confidence value */ + bpi_ID_CUE, /** (Cue) general purpose cue */ + bpi_ID_PCA_MAT, /** eigenvector matrix obtained from PCA analysis */ + bpi_ID_PCA_AVG, /** PCA average vector */ + bpi_ID_PCA_EVL, /** PCA eigen values */ + bpi_ID_COMMENT /** (ASCII String) comment or description of data */ + // never modify this list alone (!) - modification must be initiated in Kernel/API +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +#endif /* bpi_TYPES_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/APh.c b/Embedded/common/src/b_BasicEm/APh.c new file mode 100644 index 0000000..dd53ad9 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/APh.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/APh.h" +#include "b_BasicEm/Complex.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +flag bbs_APh_equal( struct bbs_APh aph1A, + struct bbs_APh aph2A ) +{ + return ( aph1A.absE == aph2A.absE ) && ( aph1A.phaseE == aph2A.phaseE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APh_memSize( struct bbs_Context* cpA, + struct bbs_APh aPhA ) +{ + return bbs_SIZEOF16( aPhA.absE ) + bbs_SIZEOF16( aPhA.phaseE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APh_memWrite( struct bbs_Context* cpA, + const struct bbs_APh* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite16( &ptrA->absE, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->phaseE, memPtrA ); + return bbs_APh_memSize( cpA, *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APh_memRead( struct bbs_Context* cpA, + struct bbs_APh* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead16( &ptrA->absE, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->phaseE, memPtrA ); + return bbs_APh_memSize( cpA, *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +struct bbs_APh bbs_APh_conj( const struct bbs_APh aPhA ) +{ + struct bbs_APh aphL; + aphL.absE = aPhA.absE; + aphL.phaseE = - aPhA.phaseE; + return aphL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_APh_importComplex( struct bbs_APh* dstPtrA, + const struct bbs_Complex* srcPtrA ) +{ + dstPtrA->absE = bbs_sqrt32( ( int32 ) srcPtrA->realE * srcPtrA->realE + ( int32 ) srcPtrA->imagE * srcPtrA->imagE ); + dstPtrA->phaseE = bbs_phase16( srcPtrA->realE, srcPtrA->imagE ); +} + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/APh.h b/Embedded/common/src/b_BasicEm/APh.h new file mode 100644 index 0000000..39cc7e1 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/APh.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_APH_H +#define bbs_APH_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_Complex; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** Object representing absolute and phase value of a complex number */ +struct bbs_APh +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** absolute value */ + uint16 absE; + + /** phase value */ + phase16 phaseE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** equal operator */ +flag bbs_APh_equal( struct bbs_APh aph1A, + struct bbs_APh aph2A ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size in 16-bit words object needs when written to memory */ +uint32 bbs_APh_memSize( struct bbs_Context* cpA, + struct bbs_APh aPhA ); + +/** writes object to memory; returns number of 16-bit words written */ +uint32 bbs_APh_memWrite( struct bbs_Context* cpA, + const struct bbs_APh* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of 16-bit words read */ +uint32 bbs_APh_memRead( struct bbs_Context* cpA, + struct bbs_APh* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** conjugated value */ +struct bbs_APh bbs_APh_conj( const struct bbs_APh aPhA ); + +/** imports complex value */ +void bbs_APh_importComplex( struct bbs_APh* dstPtrA, + const struct bbs_Complex* srcPtrA ); + +/* ------------------------------------------------------------------------- */ + +#endif /* bbs_APH_H */ diff --git a/Embedded/common/src/b_BasicEm/APhArr.c b/Embedded/common/src/b_BasicEm/APhArr.c new file mode 100644 index 0000000..7bfa0e0 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/APhArr.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/APhArr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_APhArr_init( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_APhArr_exit( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_APhArr_copy( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + const struct bbs_APhArr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_APhArr_copy(...):\n" + "Insufficient allocated memory in destination array." ); + return; + } +#endif + bbs_APhArr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy32( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE * bbs_SIZEOF32( struct bbs_APh ) ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_APhArr_equal( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA, + const struct bbs_APhArr* srcPtrA ) +{ + uint32 iL; + const struct bbs_APh* ptr1L = ptrA->arrPtrE; + const struct bbs_APh* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( !bbs_APh_equal( *ptr1L, *ptr2L ) ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APhArr_heapSize( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA, + uint32 sizeA ) +{ + return sizeA * bbs_SIZEOF16( struct bbs_APh ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_APhArr_create( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_APhArr_size( cpA, ptrA, sizeA ); + } + else + { + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( struct bbs_APh ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeA; + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_APhArr_size( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_APhArr_size( struct bbs_APhArr*, uint32 ):\n" + "Insufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APhArr_memSize( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE * bbs_SIZEOF16( struct bbs_APh ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APhArr_memWrite( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_APhArr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE * 2, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_APhArr_memRead( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_APhArr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE * 2, memPtrA ); + + if( memSizeL != bbs_APhArr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_APhArr_memRead( const struct bbs_APhArr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/APhArr.h b/Embedded/common/src/b_BasicEm/APhArr.h new file mode 100644 index 0000000..9a70d83 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/APhArr.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_APH_ARR_EM_H +#define bbs_APH_ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" +#include "b_BasicEm/APh.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** abs phase array */ +struct bbs_APhArr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of bytes */ + struct bbs_APh* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_APhArr */ +void bbs_APhArr_init( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA ); + +/** frees bbs_APhArr */ +void bbs_APhArr_exit( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_APhArr_copy( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + const struct bbs_APhArr* srcPtrA ); + +/** equal operator */ +flag bbs_APhArr_equal( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA, + const struct bbs_APhArr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_APhArr_heapSize( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** creates bbs_APhArr object. + * This function must be called after initialization before usage of + * object. + */ +void bbs_APhArr_create( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_APhArr_size( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_APhArr_memSize( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bbs_APhArr_memWrite( struct bbs_Context* cpA, + const struct bbs_APhArr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bbs_APhArr_memRead( struct bbs_Context* cpA, + struct bbs_APhArr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +#endif /* bbs_APH_ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Basic.h b/Embedded/common/src/b_BasicEm/Basic.h new file mode 100644 index 0000000..2e75f68 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Basic.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_BASIC_EM_H +#define bbs_BASIC_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +/** This header file is not part of the repository. + * If you get an error message at this point, copy + * b_BasicEm/LibConfigDefault.h into + * "../conf/b_BasicEm/LibConfig.h" + */ +#include "../conf/b_BasicEm/LibConfig.h" + +#include "b_BasicEm/Config.h" + +/* ---- defines ------------------------------------------------------------ */ + +#if defined( WIN32 ) + /* disable warning for short += short: */ + #pragma warning( disable : 4244 ) +#endif + +#if defined( bbs_NO_MESSAGE_HANDLING ) +#error bbs_NO_MESSAGE_HANDLING is obsolete, please use bbs_COMPACT_MESSAGE_HANDLING instead. +#endif +#if defined( bbs_ENABLE_MESSAGE_FPTRG ) +#error bbs_ENABLE_MESSAGE_FPTRG is obsolete, please use error handler in context object instead. +#endif + +#if defined( bbs_NO_MESSAGE_HANDLING ) && defined( bbs_ENABLE_MESSAGE_FPTRG ) +#error LibConfig.h: bbs_NO_MESSAGE_HANDLING and bbs_ENABLE_MESSAGE_FPTRG are mutually exclusive +#endif + + + +/* ---- typedefs ----------------------------------------------------------- */ + +typedef signed char int8; +typedef signed short int16; +typedef unsigned char uint8; +typedef unsigned short uint16; + +#if defined HW_TMS320C6x + typedef signed int int32; + typedef unsigned int uint32; + typedef uint32 count_t; +#elif defined HW_TMS320C5x + typedef signed long int32; + typedef unsigned long uint32; + typedef uint16 count_t; +#else + typedef signed int int32; + typedef unsigned int uint32; + typedef uint32 count_t; +#endif + + +typedef uint32 flag; /* boolean type */ + +/* + Please modify the 64 bit types declarations below for specific platforms/compilers + where necessary; + bbs_TYPES_64_AVAILABLE should be checked in code sections that make use of 64 bit data types. +*/ +#ifdef bbs_TYPES_64_AVAILABLE + +#ifdef WIN64 + typedef __int64 int64; + typedef unsigned __int64 uint64; +#else + typedef long long int64; + typedef unsigned long long uint64; +#endif + +#endif /* bbs_TYPES_64_AVAILABLE */ + +/** floating point type */ +struct flt16 +{ + int16 valE; + int16 bbpE; +}; + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +#ifndef NULL + #define NULL 0L +#endif + +#define bbs_MAX_STRING_LENGTH 1024 + +/* ---- macros ------------------------------------------------------------- */ + +/** device independent macro definitions for sizeof: + * bbs_SIZEOF8: size in bytes + * bbs_SIZEOF16: size in 16-bit words + * bbs_SIZEOF32: size in 32-bit words + */ +#if defined( HW_TMS320C5x ) + #define bbs_SIZEOF8( typeA ) ( sizeof( typeA ) << 1 ) + #define bbs_SIZEOF16( typeA ) ( sizeof( typeA ) ) + #define bbs_SIZEOF32( typeA ) ( sizeof( typeA ) >> 1 ) +#else + #define bbs_SIZEOF8( typeA ) ( sizeof( typeA ) ) + #define bbs_SIZEOF16( typeA ) ( sizeof( typeA ) >> 1 ) + #define bbs_SIZEOF32( typeA ) ( sizeof( typeA ) >> 2 ) +#endif + +/** messages */ +#if defined( HW_TMS320C5x ) || defined( bbs_COMPACT_MESSAGE_HANDLING ) + + #define bbs_DEF_fNameL( fNameA ) + + #define bbs_ERROR0( formatA ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, NULL ) ) + #define bbs_ERROR1( formatA, arg1A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, NULL ) ) + #define bbs_ERROR2( formatA, arg1A, arg2A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, NULL ) ) + #define bbs_ERROR3( formatA, arg1A, arg2A, arg3A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, NULL ) ) + #define bbs_ERROR4( formatA, arg1A, arg2A, arg3A, arg4A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, NULL ) ) + #define bbs_ERROR5( formatA, arg1A, arg2A, arg3A, arg4A, arg5A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, NULL ) ) + + #define bbs_ERR0( errorA, formatA ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, NULL ) ) + #define bbs_ERR1( errorA, formatA, arg1A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, NULL ) ) + #define bbs_ERR2( errorA, formatA, arg1A, arg2A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, NULL ) ) + #define bbs_ERR3( errorA, formatA, arg1A, arg2A, arg3A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, NULL ) ) + #define bbs_ERR4( errorA, formatA, arg1A, arg2A, arg3A, arg4A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, NULL ) ) + #define bbs_ERR5( errorA, formatA, arg1A, arg2A, arg3A, arg4A, arg5A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, NULL ) ) + +#else + + #define bbs_DEF_fNameL( fNameA ) const char* fNameL = fNameA; + + #define bbs_ERROR0( formatA ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, formatA ) ) + #define bbs_ERROR1( formatA, arg1A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, formatA, arg1A ) ) + #define bbs_ERROR2( formatA, arg1A, arg2A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, formatA, arg1A, arg2A ) ) + #define bbs_ERROR3( formatA, arg1A, arg2A, arg3A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, formatA, arg1A, arg2A, arg3A ) ) + #define bbs_ERROR4( formatA, arg1A, arg2A, arg3A, arg4A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, formatA, arg1A, arg2A, arg3A, arg4A ) ) + #define bbs_ERROR5( formatA, arg1A, arg2A, arg3A, arg4A, arg5A ) bbs_Context_pushError( cpA, bbs_Error_create( bbs_ERR_ERROR, __LINE__, __FILE__, formatA, arg1A, arg2A, arg3A, arg4A, arg5A ) ) + + #define bbs_ERR0( errorA, formatA ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, formatA ) ) + #define bbs_ERR1( errorA, formatA, arg1A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, formatA, arg1A ) ) + #define bbs_ERR2( errorA, formatA, arg1A, arg2A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, formatA, arg1A, arg2A ) ) + #define bbs_ERR3( errorA, formatA, arg1A, arg2A, arg3A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, formatA, arg1A, arg2A, arg3A ) ) + #define bbs_ERR4( errorA, formatA, arg1A, arg2A, arg3A, arg4A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, formatA, arg1A, arg2A, arg3A, arg4A ) ) + #define bbs_ERR5( errorA, formatA, arg1A, arg2A, arg3A, arg4A, arg5A ) bbs_Context_pushError( cpA, bbs_Error_create( errorA, __LINE__, __FILE__, formatA, arg1A, arg2A, arg3A, arg4A, arg5A ) ) + +#endif + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +#endif /* bbs_BASIC_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Complex.c b/Embedded/common/src/b_BasicEm/Complex.c new file mode 100644 index 0000000..07c3f43 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Complex.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Complex.h" +#include "b_BasicEm/APh.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +flag bbs_Complex_equal( struct bbs_Complex compl1A, struct bbs_Complex compl2A ) +{ + return ( compl1A.realE == compl2A.realE ) && ( compl1A.imagE == compl2A.imagE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Complex_memSize( struct bbs_Context* cpA, + struct bbs_Complex complA ) +{ + return bbs_SIZEOF16( complA.realE ) + bbs_SIZEOF16( complA.imagE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Complex_memWrite( struct bbs_Context* cpA, + const struct bbs_Complex* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite16( &ptrA->realE, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->imagE, memPtrA ); + return bbs_Complex_memSize( cpA, *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Complex_memRead( struct bbs_Context* cpA, + struct bbs_Complex* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead16( &ptrA->realE, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->imagE, memPtrA ); + return bbs_Complex_memSize( cpA, *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +struct bbs_Complex bbs_Complex_conj( struct bbs_Complex complA ) +{ + struct bbs_Complex resultL; + resultL.imagE = - complA.imagE; + resultL.realE = complA.realE; + return resultL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Complex_abs2( struct bbs_Complex complA ) +{ + return ( int32 ) complA.realE * complA.realE + + ( int32 ) complA.imagE * complA.imagE; +} + +/* ------------------------------------------------------------------------- */ + +uint16 bbs_Complex_abs( struct bbs_Complex complA ) +{ + return bbs_sqrt32( bbs_Complex_abs2( complA ) ); +} + +/* ------------------------------------------------------------------------- */ + +phase16 bbs_Complex_phase( struct bbs_Complex complA ) +{ + int32 realL, imagL; + realL = complA.realE; + imagL = complA.imagE; + + return bbs_phase16( realL, imagL ); +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Complex_importAPh( struct bbs_Complex* dstPtrA, const struct bbs_APh* srcPtrA ) +{ + dstPtrA->realE = ( ( bbs_cos32( srcPtrA->phaseE ) >> 8 ) * srcPtrA->absE ) >> 16; + dstPtrA->imagE = ( ( bbs_sin32( srcPtrA->phaseE ) >> 8 ) * srcPtrA->absE ) >> 16; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/Complex.h b/Embedded/common/src/b_BasicEm/Complex.h new file mode 100644 index 0000000..fbed51e --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Complex.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_COMPLEX_H +#define bbs_COMPLEX_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_APh; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** Complex object */ +struct bbs_Complex +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** real part */ + int16 realE; + + /** imaginary part */ + int16 imagE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** equal operator */ +flag bbs_Complex_equal( struct bbs_Complex compl1A, struct bbs_Complex compl2A ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size in 16-bit words object needs when written to memory */ +uint32 bbs_Complex_memSize( struct bbs_Context* cpA, + struct bbs_Complex complA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbs_Complex_memWrite( struct bbs_Context* cpA, + const struct bbs_Complex* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbs_Complex_memRead( struct bbs_Context* cpA, + struct bbs_Complex* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** conjugated value */ +struct bbs_Complex bbs_Complex_conj( struct bbs_Complex complA ); + +/** returns squared abs value */ +uint32 bbs_Complex_abs2( struct bbs_Complex complA ); + +/** returns absolute value */ +uint16 bbs_Complex_abs( struct bbs_Complex complA ); + +/** returns phase value */ +phase16 bbs_Complex_phase( struct bbs_Complex complA ); + +/** imports abs-phase value */ +void bbs_Complex_importAPh( struct bbs_Complex* dstPtrA, const struct bbs_APh* srcPtrA ); + +/* ------------------------------------------------------------------------- */ + +#endif /* bbs_COMPLEX_H */ diff --git a/Embedded/common/src/b_BasicEm/ComplexArr.c b/Embedded/common/src/b_BasicEm/ComplexArr.c new file mode 100644 index 0000000..b667f96 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/ComplexArr.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/ComplexArr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_ComplexArr_init( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_ComplexArr_exit( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_ComplexArr_copy( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + const struct bbs_ComplexArr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_ComplexArr_copy( ... ):\n" + "Unsufficient allocated memory in destination array." ); + return; + } +#endif + bbs_ComplexArr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy32( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE * bbs_SIZEOF32( struct bbs_Complex ) ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_ComplexArr_equal( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA, + const struct bbs_ComplexArr* srcPtrA ) +{ + uint32 iL; + const struct bbs_Complex* ptr1L = ptrA->arrPtrE; + const struct bbs_Complex* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( !bbs_Complex_equal( *ptr1L, *ptr2L ) ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_ComplexArr_heapSize( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA, + uint32 sizeA ) +{ + return sizeA * bbs_SIZEOF16( struct bbs_Complex ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_ComplexArr_create( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_ComplexArr_size( cpA, ptrA, sizeA ); + } + else + { + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( struct bbs_Complex ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeA; + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_ComplexArr_size( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_ComplexArr_size( struct bbs_ComplexArr*, uint32 sizeA ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_ComplexArr_memSize( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA ) + +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE * bbs_SIZEOF16( struct bbs_Complex ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_ComplexArr_memWrite( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_ComplexArr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE * 2, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_ComplexArr_memRead( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_ComplexArr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE * 2, memPtrA ); + + if( memSizeL != bbs_ComplexArr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_ComplexArr_memRead( const struct bbs_ComplexArr* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/ComplexArr.h b/Embedded/common/src/b_BasicEm/ComplexArr.h new file mode 100644 index 0000000..328920a --- /dev/null +++ b/Embedded/common/src/b_BasicEm/ComplexArr.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_COMPLEX_ARR_EM_H +#define bbs_COMPLEX_ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" +#include "b_BasicEm/Complex.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** complex array */ +struct bbs_ComplexArr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of bytes */ + struct bbs_Complex* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_ComplexArr */ +void bbs_ComplexArr_init( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA ); + +/** frees bbs_ComplexArr */ +void bbs_ComplexArr_exit( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_ComplexArr_copy( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + const struct bbs_ComplexArr* srcPtrA ); + +/** equal operator */ +flag bbs_ComplexArr_equal( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA, + const struct bbs_ComplexArr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_ComplexArr_heapSize( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** creates bbs_ComplexArr object */ +void bbs_ComplexArr_create( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_ComplexArr_size( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size in 16-bit words object needs when written to memory */ +uint32 bbs_ComplexArr_memSize( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbs_ComplexArr_memWrite( struct bbs_Context* cpA, + const struct bbs_ComplexArr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbs_ComplexArr_memRead( struct bbs_Context* cpA, + struct bbs_ComplexArr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +#endif /* bbs_COMPLEX_ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Config.h b/Embedded/common/src/b_BasicEm/Config.h new file mode 100644 index 0000000..06d37c0 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Config.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_CONFIG_EM_H +#define bbs_CONFIG_EM_H + +/** + * This file contains hardware and OS specific definitions + */ + +/* ---- release specific defines ------------------------------------------- */ + +/* ---- hardware specific defines ------------------------------------------ */ + +#if defined( HW_i586 ) || defined( HW_i686 ) + #ifdef HW_SSE2 + #define bbs_MEMORY_ALIGNMENT 16 /* SSE2: align data to 128 bits */ + #else + #define bbs_MEMORY_ALIGNMENT 8 /* MMX: align data to 64 bits */ + #endif +#elif defined( HW_EE ) + #define bbs_MEMORY_ALIGNMENT 16 /* align EE-MMI data to 128 bits */ +#else + #define bbs_MEMORY_ALIGNMENT 1 +#endif + +#ifdef HW_TMS470R2X + #pragma message("Warning: deprecated define HW_TMS470R2X, use HW_ARMv4 instead") + #define HW_ARMv4 +#endif + +#ifdef HW_ARM9E + #pragma message("Warning: deprecated define HW_ARM9E, use HW_ARMv5TE instead") + #define HW_ARMv5TE +#endif + +/* ---- operating system specific defines ---------------------------------- */ + +#if defined( WIN32 ) || defined( _WIN32_WCE ) + /* disable warning "unreferenced formal parameter": */ + #pragma warning( disable : 4100 ) + + /* disable warning for constant expression in condition: */ + #pragma warning( disable : 4127 ) + + /* disable warning for short += short: */ + #pragma warning( disable : 4244 ) + + /* disable warning 'unreachable code' in release build: */ + /* this warning occurs due to a wrong code evaluation of the compiler */ + #pragma warning( disable : 4702 ) + + /* disable warning for not expanded inline functions in release build: */ + #pragma warning( disable : 4710 ) + + /* disable warning for automatic expanded inline functions in release build: */ + #pragma warning( disable : 4711 ) + + /* disable warning "unreferenced inline function has been removed": */ + #pragma warning( disable : 4514 ) + +#endif + +/* -------------------------------------------------------------------------- */ + +#endif /* bbs_CONFIG_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Context.c b/Embedded/common/src/b_BasicEm/Context.c new file mode 100644 index 0000000..02f52c8 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Context.c @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Context.h" +#include "b_BasicEm/String.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Context_init( struct bbs_Context* cpA ) +{ + uint32 iL; + for( iL = 0; iL < bbs_CONTEXT_MAX_ERRORS; iL++ ) + { + cpA->errStackE[ iL ].errorE = bbs_ERR_OK; + cpA->errStackE[ iL ].fileE[ 0 ] = 0; + cpA->errStackE[ iL ].lineE = 0; + cpA->errStackE[ iL ].textE[ 0 ] = 0; + } + + cpA->errIndexE = 0; + + bbs_MemTbl_init( cpA, &cpA->memTblE ); + + for( iL = 0; iL < bbs_CONTEXT_MAX_MEM_MANAGERS; iL++ ) + { + bbs_DynMemManager_init( cpA, &cpA->dynMemManagerArrE[ iL ] ); + } + + cpA->dynMemManagerArrSizeE = 0; + cpA->errorHandlerE = NULL; + cpA->callbackHandlerE = NULL; + cpA->userPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Context_exit( struct bbs_Context* cpA ) +{ + uint32 iL; + for( iL = 0; iL < bbs_CONTEXT_MAX_ERRORS; iL++ ) + { + cpA->errStackE[ iL ].errorE = bbs_ERR_OK; + cpA->errStackE[ iL ].fileE[ 0 ] = 0; + cpA->errStackE[ iL ].lineE = 0; + cpA->errStackE[ iL ].textE[ 0 ] = 0; + } + + cpA->errIndexE = 0; + + bbs_MemTbl_exit( cpA, &cpA->memTblE ); + + for( iL = 0; iL < cpA->dynMemManagerArrSizeE; iL++ ) + { + bbs_DynMemManager_freeAll( cpA, &cpA->dynMemManagerArrE[ iL ] ); + } + + for( iL = 0; iL < bbs_CONTEXT_MAX_MEM_MANAGERS; iL++ ) + { + bbs_DynMemManager_exit( cpA, &cpA->dynMemManagerArrE[ iL ] ); + } + + cpA->dynMemManagerArrSizeE = 0; + cpA->errorHandlerE = NULL; + cpA->callbackHandlerE = NULL; + cpA->userPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA ) +{ + bbs_ERROR0( "void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA ):\n" + "A comtext object cannot be copied" ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bbs_Error bbs_Error_create( uint32 errorA, + uint32 lineA, + const char* fileA, + const char* textA, + ... ) +{ + struct bbs_Error errorL; + errorL.errorE = errorA; + errorL.lineE = lineA; + + if( fileA != NULL ) + { + uint32 lenL = bbs_strlen( fileA ); + uint32 ofsL = ( lenL + 1 > bbs_ERROR_MAX_FILE_CHARS ) ? lenL + 1 - bbs_ERROR_MAX_FILE_CHARS : 0; + bbs_strcpy( errorL.fileE, fileA + ofsL ); + } + else + { + errorL.fileE[ 0 ] = 0; + } + + if( textA != NULL ) + { + va_list argsL; + va_start( argsL, textA ); + bbs_vsnprintf( errorL.textE, bbs_ERROR_MAX_TEXT_CHARS, textA, argsL ); + va_end( argsL ); + } + else + { + errorL.textE[ 0 ] = 0; + } + + return errorL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +flag bbs_Context_pushError( struct bbs_Context* cpA, struct bbs_Error errorA ) +{ + flag returnL = FALSE; + if( cpA->errIndexE < bbs_CONTEXT_MAX_ERRORS ) + { + cpA->errStackE[ cpA->errIndexE++ ] = errorA; + returnL = TRUE; + } + + if( cpA->errorHandlerE != NULL ) + { + cpA->errorHandlerE( cpA ); + } + + return returnL; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_Error bbs_Context_popError( struct bbs_Context* cpA ) +{ + if( cpA->errIndexE > 0 ) + { + return cpA->errStackE[ --( cpA->errIndexE ) ]; + } + else + { + return cpA->errStackE[ 0 ]; + } +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_Error bbs_Context_peekError( struct bbs_Context* cpA ) +{ + if( cpA->errIndexE > 0 ) + { + return cpA->errStackE[ cpA->errIndexE - 1 ]; + } + else + { + return cpA->errStackE[ 0 ]; + } +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_Context_error( struct bbs_Context* cpA ) +{ + return cpA->errIndexE > 0; +} + +/* ------------------------------------------------------------------------- */ + +bbs_errorFPtr bbs_Context_setErrorHandler( struct bbs_Context* cpA, + bbs_errorFPtr errorHandlerA ) +{ + bbs_errorFPtr oldErrorHandlerL = cpA->errorHandlerE; + cpA->errorHandlerE = errorHandlerA; + return oldErrorHandlerL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Context_doCallback( struct bbs_Context* cpA ) +{ + if( cpA->callbackHandlerE != NULL ) + { + uint32 errorL = ( *cpA->callbackHandlerE )( cpA ); + if( errorL != bbs_ERR_OK ) + { + bbs_Context_pushError( cpA, bbs_Error_create( errorL, 0, NULL, NULL ) ); + } + } +} + +/* ------------------------------------------------------------------------- */ + +bbs_callbackFPtr bbs_Context_setCallbackHandler( struct bbs_Context* cpA, + bbs_callbackFPtr callbackHandlerA ) +{ + bbs_callbackFPtr oldCallbackHandlerL = cpA->callbackHandlerE; + cpA->callbackHandlerE = callbackHandlerA; + return oldCallbackHandlerL; +} + +/* ------------------------------------------------------------------------- */ + +/** adds a static memory segment to memory table of context */ +void bbs_Context_addStaticSeg( struct bbs_Context* cpA, + uint16* memPtrA, /* pointer to memory */ + uint32 sizeA, /* size of memory segment in 16 bit units */ + flag sharedA, /* Indicates that this segment is to be shared among multiple objects */ + uint32 idA ) /* ID of segment, id=0: unspecified */ +{ + struct bbs_MemSeg memSegL; + bbs_DEF_fNameL( "void bbs_Context_addStaticSeg(....)" ) + + + /* checks */ + if( sharedA && cpA->memTblE.ssSizeE == bbs_MAX_MEM_SEGS ) + { + bbs_ERROR1( "%s:\nShared Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); + return; + } + if( sharedA && cpA->memTblE.esSizeE == bbs_MAX_MEM_SEGS ) + { + bbs_ERROR1( "%s:\nExclusive Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); + return; + } + + + bbs_MemSeg_init( cpA, &memSegL ); + memSegL.memPtrE = memPtrA; + memSegL.sizeE = sizeA; + memSegL.allocIndexE = 0; + memSegL.sharedE = sharedA; + memSegL.idE = idA; + memSegL.dynMemManagerPtrE = NULL; + + if( sharedA ) + { + cpA->memTblE.ssArrE[ cpA->memTblE.ssSizeE++ ] = memSegL; + } + else + { + cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ] = memSegL; + cpA->memTblE.espArrE[ cpA->memTblE.esSizeE ] = &cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ]; + cpA->memTblE.esSizeE++; + } +} + +/* ------------------------------------------------------------------------- */ + +/* adds a dynamic memory segment to memory table of context + * Upon destruction of the context object any residual will be freed automatically + */ +void bbs_Context_addDynamicSeg( struct bbs_Context* cpA, + bbs_mallocFPtr mallocFPtrA, /* function pointer to external mem alloc function (s. comment of type declaration)*/ + bbs_freeFPtr freeFPtrA, /* function pointer to external mem free function */ + flag sharedA, /* Indicates that this segment is to be shared among multiple objects */ + uint32 idA ) /* ID of segment, id=0: unspecified */ +{ + struct bbs_DynMemManager memManagerL; + struct bbs_MemSeg memSegL; + bbs_DEF_fNameL( "void bbs_Context_addDynamicSeg(....)" ) + + + /* checks */ + if( cpA->dynMemManagerArrSizeE == bbs_CONTEXT_MAX_MEM_MANAGERS ) + { + bbs_ERROR1( "%s:\nMemory Manager Table is full! Increase bbs_CONTEXT_MAX_MEM_MANAGERS", fNameL ); + return; + } + if( sharedA && cpA->memTblE.ssSizeE == bbs_MAX_MEM_SEGS ) + { + bbs_ERROR1( "%s:\nShared Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); + return; + } + if( sharedA && cpA->memTblE.esSizeE == bbs_MAX_MEM_SEGS ) + { + bbs_ERROR1( "%s:\nExclusive Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); + return; + } + + bbs_DynMemManager_init( cpA, &memManagerL ); + memManagerL.mallocFPtrE = mallocFPtrA; + memManagerL.freeFPtrE = freeFPtrA; + memManagerL.memPtrE = NULL; + cpA->dynMemManagerArrE[ cpA->dynMemManagerArrSizeE++ ] = memManagerL; + + bbs_MemSeg_init( cpA, &memSegL ); + memSegL.memPtrE = NULL; + memSegL.sizeE = 0; + memSegL.allocIndexE = 0; + memSegL.sharedE = sharedA; + memSegL.idE = idA; + memSegL.dynMemManagerPtrE = &cpA->dynMemManagerArrE[ cpA->dynMemManagerArrSizeE - 1 ]; + + if( sharedA ) + { + cpA->memTblE.ssArrE[ cpA->memTblE.ssSizeE++ ] = memSegL; + } + else + { + cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ] = memSegL; + cpA->memTblE.espArrE[ cpA->memTblE.esSizeE ] = &cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ]; + cpA->memTblE.esSizeE++; + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Context_exclAllocSize( struct bbs_Context* cpA, uint32 segIndexA ) +{ + return bbs_MemSeg_allocatedSize( cpA, &cpA->memTblE.esArrE[ segIndexA ] ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Context_shrdAllocSize( struct bbs_Context* cpA, uint32 segIndexA ) +{ + return bbs_MemSeg_allocatedSize( cpA, &cpA->memTblE.ssArrE[ segIndexA ] ); +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Context_quickInit( struct bbs_Context* cpA, + bbs_mallocFPtr mallocFPtrA, /* function pointer to external mem alloc function (s. comment of type declaration)*/ + bbs_freeFPtr freeFPtrA, + bbs_errorFPtr errorHandlerA ) +{ + bbs_Context_init( cpA ); + bbs_Context_addDynamicSeg( cpA, mallocFPtrA, freeFPtrA, FALSE, 0 ); + bbs_Context_addDynamicSeg( cpA, mallocFPtrA, freeFPtrA, TRUE, 0 ); + bbs_Context_setErrorHandler( cpA, errorHandlerA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/Context.h b/Embedded/common/src/b_BasicEm/Context.h new file mode 100644 index 0000000..7ea323b --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Context.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_CONTEXT_EM_H +#define bbs_CONTEXT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BasicEm/DynMemManager.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_Context; + +/* ---- typedefs ----------------------------------------------------------- */ + +/** error handler function pointer */ +typedef void ( *bbs_errorFPtr )( struct bbs_Context* cpA ); + +/** callback handler function pointer */ +typedef uint32 ( *bbs_callbackFPtr )( struct bbs_Context* cpA ); + +/* ---- constants ---------------------------------------------------------- */ + +#define bbs_CONTEXT_MAX_ERRORS 8 +#define bbs_CONTEXT_MAX_MEM_MANAGERS 8 + +#ifdef bbs_COMPACT_MESSAGE_HANDLING +/* characters allocated for file name string (string is stored rightbound) (minimum 1)*/ +#define bbs_ERROR_MAX_FILE_CHARS 24 +/* characters allocated for text message (minimum 1) */ +#define bbs_ERROR_MAX_TEXT_CHARS 1 +#else +/* characters allocated for file name string (string is stored rightbound) (minimum 1)*/ +#define bbs_ERROR_MAX_FILE_CHARS 52 +/* characters allocated for text message (minimum 1) */ +#define bbs_ERROR_MAX_TEXT_CHARS 256 +#endif + +/* defined error codes */ +#define bbs_ERR_OK 0 /* no error condition */ +#define bbs_ERR_ERROR 1 /* generic error */ +#define bbs_ERR_OUT_OF_MEMORY 2 /* malloc handler returns with NULL*/ +#define bbs_ERR_MEMORY_OVERFLOW 3 /* not enough memory in a segment or no segment */ +#define bbs_ERR_WRONG_VERSION 4 /* incompatible version in ..._memRead() */ +#define bbs_ERR_CORRUPT_DATA 5 /* corrupt data in ..._memRead()*/ +#define bbs_ERR_CALLBACK_ERROR 6 /* a defined error originiating from a callback function */ + +/* ---- object definition -------------------------------------------------- */ + +/** error object */ +struct bbs_Error +{ + /* error code */ + uint32 errorE; + + /* line number */ + uint32 lineE; + + /* file name */ + char fileE[ bbs_ERROR_MAX_FILE_CHARS ]; + + /* error text */ + char textE[ bbs_ERROR_MAX_TEXT_CHARS ]; +}; + +/* ------------------------------------------------------------------------- */ + +/** context object */ +struct bbs_Context +{ + + /* ---- private data --------------------------------------------------- */ + + /** error stack */ + struct bbs_Error errStackE[ bbs_CONTEXT_MAX_ERRORS ]; + + /** error stack index */ + uint32 errIndexE; + + /** memory table */ + struct bbs_MemTbl memTblE; + + /** multiple purpose dynamic memory managers */ + struct bbs_DynMemManager dynMemManagerArrE[ bbs_CONTEXT_MAX_MEM_MANAGERS ]; + + /** number of used memory managers */ + uint32 dynMemManagerArrSizeE; + + /** error function handler */ + bbs_errorFPtr errorHandlerE; + + /** callback function handler */ + bbs_callbackFPtr callbackHandlerE; + + /** user-defined pointer */ + void* userPtrE; + + /* ---- public data ---------------------------------------------------- */ + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_Context */ +void bbs_Context_init( struct bbs_Context* cpA ); + +/** frees bbs_Context */ +void bbs_Context_exit( struct bbs_Context* cpA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** composes an error object */ +struct bbs_Error bbs_Error_create( uint32 errorA, uint32 lineA, const char* fileA, const char* textA, ... ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/****** ERROR HANDLING *********/ + +/** puts an error onto the error stack (returns false if stack was already full) */ +flag bbs_Context_pushError( struct bbs_Context* cpA, struct bbs_Error errorA ); + +/** takes the last error from stack and returns it (when stack is empty: returns the error at stack position 0)*/ +struct bbs_Error bbs_Context_popError( struct bbs_Context* cpA ); + +/** returns the last error of stack without removing it (when stack is empty: returns the error at stack position 0)*/ +struct bbs_Error bbs_Context_peekError( struct bbs_Context* cpA ); + +/** returns true if the error stack is not empty */ +flag bbs_Context_error( struct bbs_Context* cpA ); + +/** sets error handler; returns pointer to previous error handler + * Pointer to Error handler can be NULL (->no handler call) + * The error handler is called by function pushError diectly after an error was posted + */ +bbs_errorFPtr bbs_Context_setErrorHandler( struct bbs_Context* cpA, + bbs_errorFPtr errorHandlerA ); + +/*******************************/ + +/****** CALLBACK HANDLING ******/ + +/** call the callback handler, push error if return value is != bbs_ERR_OK */ +void bbs_Context_doCallback( struct bbs_Context* cpA ); + +/** sets callback handler; returns pointer to previous callback handler + * Pointer to callback handler can be NULL (->no handler call) + * The callback handler is called by function doCallback + */ +bbs_callbackFPtr bbs_Context_setCallbackHandler( struct bbs_Context* cpA, + bbs_callbackFPtr callbackHandlerA ); + +/*******************************/ + +/******* MEMORY HANDLING *******/ + +/** adds a static memory segment to memory table of context */ +void bbs_Context_addStaticSeg( struct bbs_Context* cpA, + uint16* memPtrA, /* pointer to memory (32bit aligned)*/ + uint32 sizeA, /* size of memory segment in 16 bit units */ + flag sharedA, /* Indicates that this segment is to be shared among multiple objects */ + uint32 idA ); /* ID of segment, id=0: unspecified */ + +/* adds a dynamic memory segment to memory table of context + * Upon destruction of the context object any residual will be freed automatically + */ +void bbs_Context_addDynamicSeg( struct bbs_Context* cpA, + bbs_mallocFPtr mallocFPtrA, /* function pointer to external mem alloc function (s. comment of type declaration)*/ + bbs_freeFPtr freeFPtrA, /* function pointer to external mem free function */ + flag sharedA, /* Indicates that this segment is to be shared among multiple objects */ + uint32 idA ); /* ID of segment, id=0: unspecified */ + + +/** Returns allocated memory in selected exclusive segment in units of 16bits */ +uint32 bbs_Context_exclAllocSize( struct bbs_Context* cpA, uint32 segIndexA ); + +/** Returns allocated memory in selected exclusive segment in units of 16bits + * Note that in case of static memory the return value might not reflect + * the actually allocated memory amount. + */ +uint32 bbs_Context_shrdAllocSize( struct bbs_Context* cpA, uint32 segIndexA ); + +/*******************************/ + + +/** quick compact setup for dynamic memory management environment + * creates an initialized segment with + * - one dynamic exclusive segment + * - one dynamic shared segment + * - error handler (can be NULL) + * + * Don't forget to call bbs_Context_exit on returned context if it goes out of scope + */ +void bbs_Context_quickInit( struct bbs_Context* cpA, + bbs_mallocFPtr mallocFPtrA, /* function pointer to external mem alloc function (s. comment of type declaration)*/ + bbs_freeFPtr freeFPtrA, + bbs_errorFPtr errorHandlerA ); + + +#endif /* bbs_CONTEXT_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/DynMemManager.c b/Embedded/common/src/b_BasicEm/DynMemManager.c new file mode 100644 index 0000000..523b939 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/DynMemManager.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/DynMemManager.h" +#include "b_BasicEm/Context.h" + +/* ------------------------------------------------------------------------- */ + +/* minimum block size dynamically allocated in function nextBlock (affects only shared memory) */ +#define bbs_DYN_MEM_MIN_NEW_BLOCK_SIZE 0 + +/** Offset to actual memory area on allocated memory blocks (in 16-bit words). + * Value needs to be large enough to hold the pointer to the next memory block + * and the size value (32-bit) of the memory area. + */ +#define bbs_MEM_OFFSET 6 + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_DynMemManager_init( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA ) +{ + ptrA->memPtrE = NULL; + ptrA->mallocFPtrE = NULL; + ptrA->freeFPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_DynMemManager_exit( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA ) +{ + ptrA->memPtrE = NULL; + ptrA->mallocFPtrE = NULL; + ptrA->freeFPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_DynMemManager_allocatedSize( struct bbs_Context* cpA, + const struct bbs_DynMemManager* ptrA ) +{ + uint32 sizeL = 0; + uint16* pL = ( uint16* )ptrA->memPtrE; + while( pL != NULL ) + { + sizeL += ( ( uint32* )pL )[ 2 ]; + pL = *( uint16** )pL; + } + return sizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint16* bbs_DynMemManager_alloc( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA, + const struct bbs_MemSeg* memSegPtrA, + uint32 sizeA ) +{ + uint16* pL = NULL; + bbs_DEF_fNameL( "uint16* bbs_DynMemManager_alloc( struct bbs_DynMemManager* ptrA, uint32 sizeA )" ) + + + if( ptrA->mallocFPtrE == NULL ) + { + bbs_ERROR1( "%s:\n Malloc handler not defined.\n", fNameL ); + return NULL; + } + + if( ptrA->memPtrE == NULL ) + { + ptrA->memPtrE = ptrA->mallocFPtrE( cpA, memSegPtrA, ( sizeA + bbs_MEM_OFFSET ) << 1 ); + pL = ptrA->memPtrE; + } + else + { + uint16** ppL = ( uint16** )ptrA->memPtrE; + while( *ppL != NULL ) ppL = ( uint16** )*ppL; + *ppL = ptrA->mallocFPtrE( cpA, memSegPtrA, ( sizeA + bbs_MEM_OFFSET ) << 1 ); + pL = *ppL; + } + + if( pL == NULL ) + { + bbs_ERR1( bbs_ERR_OUT_OF_MEMORY, "%s:\n Allocation failed.\n", fNameL ); + return NULL; + } + + ( ( uint32* )pL )[ 0 ] = 0; + ( ( uint32* )pL )[ 1 ] = 0; + ( ( uint32* )pL )[ 2 ] = sizeA + bbs_MEM_OFFSET; + + return pL + bbs_MEM_OFFSET; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_DynMemManager_free( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA, + uint16* memPtrA ) +{ + bbs_DEF_fNameL( "void bbs_DynMemManager_free( .... )" ) + + if( ptrA->memPtrE == NULL ) + { + bbs_ERROR1( "%s:\n Memory was not allocated.\n", fNameL ); + return; + } + else if( ptrA->memPtrE + bbs_MEM_OFFSET == memPtrA ) + { + uint16* memPtrL = ptrA->memPtrE; + ptrA->memPtrE = *( uint16** )ptrA->memPtrE; + ptrA->freeFPtrE( memPtrL ); + } + else + { + uint16* p0L = NULL; + uint16* pL = ( uint16* )ptrA->memPtrE; + + while( pL != NULL ) + { + if( pL + bbs_MEM_OFFSET == memPtrA ) break; + p0L = pL; + pL = *( uint16** )pL; + } + + if( pL != NULL ) + { + if( ptrA->freeFPtrE == NULL ) + { + bbs_ERROR1( "%s:\n Free handler not defined.\n", fNameL ); + return; + } + + if( p0L != NULL ) + { + *( uint16** )p0L = *( uint16** )pL; + } + else + { + ptrA->memPtrE = *( uint16** )pL; + } + + ptrA->freeFPtrE( pL ); + } + else + { + bbs_ERROR1( "%s:\n Attempt to free memory that was not allocated.\n", fNameL ); + return; + } + } +} + +/* ------------------------------------------------------------------------- */ + +uint16* bbs_DynMemManager_nextBlock( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA, + const struct bbs_MemSeg* memSegPtrA, + uint16* curBlockPtrA, + uint32 minSizeA, + uint32* actualSizePtrA ) +{ + uint16* pL = ( uint16* )ptrA->memPtrE; + bbs_DEF_fNameL( "uint16* bbs_DynMemManager_nextBlock( .... )" ) + + if( curBlockPtrA != NULL ) + { + /* find current block */ + while( pL != NULL ) + { + if( pL + bbs_MEM_OFFSET == curBlockPtrA ) break; + pL = *( uint16** )pL; + } + + if( pL == NULL ) + { + bbs_ERROR1( "%s:\nCould not find current memory block.\n", fNameL ); + *actualSizePtrA = 0; + return NULL; + } + + /* go to next block */ + pL = *( uint16** )pL; + } + + /* find next fitting block */ + while( pL != NULL ) + { + if( ( ( uint32* )pL )[ 2 ] >= minSizeA + bbs_MEM_OFFSET ) break; + pL = *( uint16** )pL; + } + + if( pL == NULL ) + { + /* no proper block -> allocate new one */ + uint32 blockSizeL = minSizeA > bbs_DYN_MEM_MIN_NEW_BLOCK_SIZE ? minSizeA : bbs_DYN_MEM_MIN_NEW_BLOCK_SIZE; + uint16* memPtrL = bbs_DynMemManager_alloc( cpA, ptrA, memSegPtrA, blockSizeL ); + if( memPtrL != NULL ) + { + *actualSizePtrA = blockSizeL; + } + else + { + *actualSizePtrA = 0; + } + return memPtrL; + } + else + { + *actualSizePtrA = ( ( uint32* )pL )[ 2 ] - bbs_MEM_OFFSET; + return pL + bbs_MEM_OFFSET; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_DynMemManager_freeAll( struct bbs_Context* cpA, struct bbs_DynMemManager* ptrA ) +{ + uint16** ppL = ( uint16** )ptrA->memPtrE; + while( ppL != NULL ) + { + uint16* memPtrL = ( uint16* )ppL; + ppL = ( uint16** )*ppL; + ptrA->freeFPtrE( memPtrL ); + } + ptrA->memPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_BasicEm/DynMemManager.h b/Embedded/common/src/b_BasicEm/DynMemManager.h new file mode 100644 index 0000000..13ce084 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/DynMemManager.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_DYN_MEM_MANAGER_EM_H +#define bbs_DYN_MEM_MANAGER_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_Context; +struct bbs_MemSeg; + +/* ---- typedefs ----------------------------------------------------------- */ + +/** 'malloc' function pointer. + * Allocated memory block must be 32-bit-aligned. + * sizeA refers to the size of a memory block in bytes + */ +typedef void* ( *bbs_mallocFPtr )( struct bbs_Context* cpA, + const struct bbs_MemSeg* memSegPtrA, + uint32 sizeA ); + +/** free function pointer */ +typedef void ( *bbs_freeFPtr )( void* memPtrA ); + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** Dynamic memory manager. + * Handles allocation and deallocation of memory blocks via function pointers + * to malloc and free. + * + * Each memory block is organized as follows: + * - The first 8 bytes are reserved for the pointer to the next + * memory block (8 to allow support of 64-bit platforms). + * - Next a 32-bit value stores the allocated memory size in 16-bit units. + * - Finally the actual allocated memory area. + * This means for each new memory block an additional 12 bytes are allocated. + */ +struct bbs_DynMemManager +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to first memory block */ + uint16* memPtrE; + + /** function pointer to external mem alloc function (s. comment of type declaration)*/ + bbs_mallocFPtr mallocFPtrE; + + /** function pointer to external mem free function */ + bbs_freeFPtr freeFPtrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_DynMemManager */ +void bbs_DynMemManager_init( struct bbs_Context* cpA, struct bbs_DynMemManager* ptrA ); + +/** frees bbs_DynMemManager */ +void bbs_DynMemManager_exit( struct bbs_Context* cpA, struct bbs_DynMemManager* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns size of currently allocated memory in 16bit units */ +uint32 bbs_DynMemManager_allocatedSize( struct bbs_Context* cpA, const struct bbs_DynMemManager* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** allocates sizeA words of memory */ +uint16* bbs_DynMemManager_alloc( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA, + const struct bbs_MemSeg* memSegPtrA, + uint32 sizeA ); + +/** frees previously allocated memory */ +void bbs_DynMemManager_free( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA, + uint16* memPtrA ); + +/** returns the next memory block of at least minSizeA length; allocates new block if neccessary */ +uint16* bbs_DynMemManager_nextBlock( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA, + const struct bbs_MemSeg* memSegPtrA, + uint16* curBlockPtrA, + uint32 minSizeA, + uint32* actualSizePtrA ); + +/** frees all allocated memory */ +void bbs_DynMemManager_freeAll( struct bbs_Context* cpA, + struct bbs_DynMemManager* ptrA ); + + +#endif /* bbs_DYN_MEM_MANAGER_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Functions.c b/Embedded/common/src/b_BasicEm/Functions.c new file mode 100644 index 0000000..f4a346c --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Functions.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Context.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- globals ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint16 bbs_swapBytes( uint16 valA ) +{ + return ( ( valA >> 8 ) & 0x00FF ) | ( ( valA << 8 ) & 0xFF00 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memWrite32( const void* ptrA, + uint16* memPtrA ) +{ + uint32 valL = *( uint32* )ptrA; + + #ifdef HW_BIG_ENDIAN + *memPtrA++ = bbs_swapBytes( ( uint16 )( ( valL >> 0 ) & 0xFFFF ) ); + *memPtrA++ = bbs_swapBytes( ( uint16 )( ( valL >> 16 ) & 0xFFFF ) ); + #else + *memPtrA++ = ( valL >> 0 ) & 0xFFFF; + *memPtrA++ = ( valL >> 16 ) & 0xFFFF; + #endif + + + return bbs_SIZEOF16( uint32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memRead32( void* ptrA, + const uint16* memPtrA ) +{ + uint32 valL = 0; + + #ifdef HW_BIG_ENDIAN + valL |= ( ( uint32 )bbs_swapBytes( *memPtrA++ ) << 0 ); + valL |= ( ( uint32 )bbs_swapBytes( *memPtrA++ ) << 16 ); + #else + valL |= ( ( uint32 )*memPtrA++ << 0 ); + valL |= ( ( uint32 )*memPtrA++ << 16 ); + #endif + + *( uint32* )ptrA = valL; + + return bbs_SIZEOF16( uint32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memPeek32( const uint16* memPtrA ) +{ + uint32 valL = 0; + + #ifdef HW_BIG_ENDIAN + valL |= ( ( uint32 )bbs_swapBytes( *memPtrA++ ) << 0 ); + valL |= ( ( uint32 )bbs_swapBytes( *memPtrA++ ) << 16 ); + #else + valL |= ( ( uint32 )*memPtrA++ << 0 ); + valL |= ( ( uint32 )*memPtrA++ << 16 ); + #endif + + return valL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memWrite16( const void* ptrA, + uint16* memPtrA ) +{ + #ifdef HW_BIG_ENDIAN + *memPtrA++ = bbs_swapBytes( *( uint16* )ptrA ); + #else + *memPtrA++ = *( uint16* )ptrA; + #endif + return bbs_SIZEOF16( uint16 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memRead16( void* ptrA, + const uint16* memPtrA ) +{ + #ifdef HW_BIG_ENDIAN + *( uint16* )ptrA = bbs_swapBytes( *memPtrA++ ); + #else + *( uint16* )ptrA = *memPtrA++; + #endif + + return bbs_SIZEOF16( uint16 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memWrite32Arr( struct bbs_Context* cpA, + const void* ptrA, + uint32 sizeA, uint16* memPtrA ) +{ + uint32 iL; + const uint32* srcL = ( uint32* )ptrA; + + if( bbs_Context_error( cpA ) ) return 0; + + for( iL = 0; iL < sizeA; iL++ ) + { + memPtrA += bbs_memWrite32( srcL++, memPtrA ); + } + + return sizeA * bbs_SIZEOF16( uint32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memRead32Arr( struct bbs_Context* cpA, + void* ptrA, + uint32 sizeA, + const uint16* memPtrA ) +{ + uint32 iL; + uint32* dstL = ( uint32* )ptrA; + + if( bbs_Context_error( cpA ) ) return 0; + + for( iL = 0; iL < sizeA; iL++ ) + { + memPtrA += bbs_memRead32( dstL++, memPtrA ); + } + + return sizeA * bbs_SIZEOF16( uint32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memWrite16Arr( struct bbs_Context* cpA, + const void* ptrA, + uint32 sizeA, + uint16* memPtrA ) +{ + uint32 iL; + const uint16* srcL = ( uint16* )ptrA; + + if( bbs_Context_error( cpA ) ) return 0; + + for( iL = 0; iL < sizeA; iL++ ) + { + memPtrA += bbs_memWrite16( srcL++, memPtrA ); + } + + return sizeA * bbs_SIZEOF16( uint16 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memRead16Arr( struct bbs_Context* cpA, + void* ptrA, + uint32 sizeA, + const uint16* memPtrA ) +{ + uint32 iL; + uint16* dstL = ( uint16* )ptrA; + + if( bbs_Context_error( cpA ) ) return 0; + + for( iL = 0; iL < sizeA; iL++ ) + { + memPtrA += bbs_memRead16( dstL++, memPtrA ); + } + + return sizeA * bbs_SIZEOF16( uint16 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memWriteUInt32( uint32 valA, + uint16* memPtrA ) +{ + #ifdef HW_BIG_ENDIAN + *memPtrA++ = bbs_swapBytes( ( uint16 )( ( valA >> 0 ) & 0xFFFF ) ); + *memPtrA++ = bbs_swapBytes( ( uint16 )( ( valA >> 16 ) & 0xFFFF ) ); + #else + *memPtrA++ = ( valA >> 0 ) & 0xFFFF; + *memPtrA++ = ( valA >> 16 ) & 0xFFFF; + #endif + + return bbs_SIZEOF16( valA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memWriteUInt16( uint16 valA, + uint16* memPtrA ) +{ + #ifdef HW_BIG_ENDIAN + *memPtrA++ = bbs_swapBytes( valA ); + #else + *memPtrA++ = valA; + #endif + + return bbs_SIZEOF16( valA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_memReadVersion32( struct bbs_Context* cpA, + uint32* versionPtrA, + uint32 refVersionA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + + bbs_memRead32( versionPtrA, memPtrA ); + if( *versionPtrA > refVersionA ) + { + bbs_ERR0( bbs_ERR_WRONG_VERSION, "uint32 bbs_memReadVersion32( .... ):\n" + "Data format is newer than software or corrupt\n" ); + } + return bbs_SIZEOF16( uint32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint16 bbs_memCheckSum16( const uint16* memPtrA, uint32 sizeA ) +{ + uint32 iL; + uint16 sumL = 0; + for( iL = 0; iL < sizeA; iL++ ) + { + #ifdef HW_BIG_ENDIAN + sumL += bbs_swapBytes( memPtrA[ iL ] ); + #else + sumL += memPtrA[ iL ]; + #endif + } + + return sumL; +} + +/* ------------------------------------------------------------------------- */ + diff --git a/Embedded/common/src/b_BasicEm/Functions.h b/Embedded/common/src/b_BasicEm/Functions.h new file mode 100644 index 0000000..c81d20d --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Functions.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_FUNCTIONS_EM_H +#define bbs_FUNCTIONS_EM_H + +/** + * This files contains gerenral purpose functions. + */ + +/* ---- includes ----------------------------------------------------------- */ +/* +#include <stdarg.h> +#include <stdlib.h> +*/ +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/String.h" +#include "b_BasicEm/Memory.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_Context; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* Memory I/O Functions */ + +/* Memory I/O Operations use the little endian data alignment + regardless of platform */ + +/** writes a 32 bit word to memory; returns bbs_SIZEOF16( uint32 ) */ +uint32 bbs_memWrite32( const void* ptrA, + uint16* memPtrA ); + +/** reads a 32 bit word from memory; returns bbs_SIZEOF16( uint32 ) */ +uint32 bbs_memRead32( void* ptrA, + const uint16* memPtrA ); + +/** reads a 32 bit word from memory and returns it */ +uint32 bbs_memPeek32( const uint16* memPtrA ); + +/** writes a 16 bit word to memory; returns bbs_SIZEOF16( uint16 ) */ +uint32 bbs_memWrite16( const void* ptrA, + uint16* memPtrA ); + +/** reads a 16 bit word from memory; returns bbs_SIZEOF16( uint16 ) */ +uint32 bbs_memRead16( void* ptrA, + const uint16* memPtrA ); + +/** writes a 32 bit word array to memory; sizeA specifies number of words in array; returns bbs_SIZEOF16( uint32 ) * sizeA */ +uint32 bbs_memWrite32Arr( struct bbs_Context* cpA, + const void* ptrA, + uint32 sizeA, uint16* memPtrA ); + +/** reads a 32 bit word array from memory; sizeA specifies number of words in array; returns bbs_SIZEOF16( uint32 ) * sizeA */ +uint32 bbs_memRead32Arr( struct bbs_Context* cpA, + void* ptrA, + uint32 sizeA, const uint16* memPtrA ); + +/** writes a 16 bit word array to memory; sizeA specifies number of words in array; returns bbs_SIZEOF16( uint16 ) * sizeA */ +uint32 bbs_memWrite16Arr( struct bbs_Context* cpA, + const void* ptrA, + uint32 sizeA, uint16* memPtrA ); + +/** reads a 16 bit word array from memory; sizeA specifies number of words in array; returns bbs_SIZEOF16( uint16 ) * sizeA */ +uint32 bbs_memRead16Arr( struct bbs_Context* cpA, + void* ptrA, + uint32 sizeA, const uint16* memPtrA ); + +/* Spcial I/O Functions */ + +/** writes a 32 bit value to memory; returns bbs_SIZEOF16( uint32 ) */ +uint32 bbs_memWriteUInt32( uint32 valA, + uint16* memPtrA ); + +/** writes a 16 bit values to memory; returns bbs_SIZEOF16( uint16 ) */ +uint32 bbs_memWriteUInt16( uint16 valA, + uint16* memPtrA ); + +/** reads a 32 bit version number word from memory. + * Compares the number to refVersionA. + * If refVersionA is lower an error condition is created. + * returns bbs_SIZEOF16( uint32 ) + */ +uint32 bbs_memReadVersion32( struct bbs_Context* cpA, + uint32* versionPtrA, + uint32 refVersionA, + const uint16* memPtrA ); + +/** return 16bit check sum of memory area (applies platform specific byte swapps) */ +uint16 bbs_memCheckSum16( const uint16* memPtrA, uint32 sizeA ); + +#endif /* bbs_FUNCTIONS_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Int16Arr.c b/Embedded/common/src/b_BasicEm/Int16Arr.c new file mode 100644 index 0000000..1d4d0ce --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Int16Arr.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Int16Arr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_init( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_exit( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_copy( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + const struct bbs_Int16Arr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->sizeE ) + { + bbs_ERROR0( "void bbs_Int16Arr_copy(...):\n" + "Insufficient allocated memory in destination array." ); + return; + } +#endif + bbs_Int16Arr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy16( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE * bbs_SIZEOF16( int16 ) ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_Int16Arr_equal( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA, + const struct bbs_Int16Arr* srcPtrA ) +{ + uint32 iL; + const int16* ptr1L = ptrA->arrPtrE; + const int16* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( *ptr1L++ != *ptr2L++ ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int16Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA, + uint32 sizeA ) +{ + return sizeA * bbs_SIZEOF16( int16 ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_create( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->sizeE == sizeA ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_Int16Arr_size( cpA, ptrA, sizeA ); + } + else + { + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( int16 ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeA; + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_createAligned( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA, + struct bbs_Int16Arr* allocPtrA, + uint32 alignBytesA ) +{ + /* allocate extra memory for alignment */ + bbs_Int16Arr_create( cpA, allocPtrA, sizeA + ( ( alignBytesA - 1 ) >> 1 ), mspA ); + + /* set members of ptrA */ + ptrA->mspE = 0; /* no own allocated memory */ + ptrA->sizeE = sizeA; + ptrA->allocatedSizeE = ptrA->sizeE; + ptrA->arrPtrE = allocPtrA->arrPtrE; + +#if defined( WIN32 ) || defined( _WIN32_WCE ) + /* disable warning "pointer truncation...": */ + #pragma warning( disable : 4311 ) +#endif + + + /* align memory */ +#ifdef bbs_TYPES_64_AVAILABLE + + while( ( ( ( uint64 ) ptrA->arrPtrE ) & ( alignBytesA - 1 ) ) ) + { + ptrA->arrPtrE++; + } +#else + while( ( ( ( uint32 ) ptrA->arrPtrE ) & ( alignBytesA - 1 ) ) ) + { + ptrA->arrPtrE++; + } +#endif + +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_size( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_Int16Arr_size( struct bbs_Int16Arr*, uint32 sizeA ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int16Arr_memSize( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE * bbs_SIZEOF16( int16 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int16Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_Int16Arr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int16Arr_memRead( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_Int16Arr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + + if( memSizeL != bbs_Int16Arr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, + "uint32 bbs_Int16Arr_memRead( const struct bbs_Int16Arr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int16Arr_fill( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + int16 valA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + ptrA->arrPtrE[ iL ] = valA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/Int16Arr.h b/Embedded/common/src/b_BasicEm/Int16Arr.h new file mode 100644 index 0000000..fbb7f39 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Int16Arr.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_INT16ARR_EM_H +#define bbs_INT16ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** short array */ +struct bbs_Int16Arr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of int16 */ + int16* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_Int16Arr */ +void bbs_Int16Arr_init( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA ); + +/** frees bbs_Int16Arr */ +void bbs_Int16Arr_exit( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_Int16Arr_copy( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + const struct bbs_Int16Arr* srcPtrA ); + +/** equal operator */ +flag bbs_Int16Arr_equal( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA, + const struct bbs_Int16Arr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_Int16Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bbs_Int16Arr */ +void bbs_Int16Arr_create( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** allocates memory for bbs_Int16Arr, + Allocation is done for allocPtrA with extra memory to allow for alignment, + aligned memory pointer is copied to ptrA. + alignBytes must be a power of 2. + bbs_Int16Arr_heapSize does not apply ! +*/ +void bbs_Int16Arr_createAligned( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA, + struct bbs_Int16Arr* allocPtrA, + uint32 alignBytesA ); + +/** sets array size */ +void bbs_Int16Arr_size( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_Int16Arr_memSize( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA ); + +/** writes object to memory; returns number of 16-bit words written */ +uint32 bbs_Int16Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_Int16Arr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of 16-bit words read */ +uint32 bbs_Int16Arr_memRead( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** fills array with a value */ +void bbs_Int16Arr_fill( struct bbs_Context* cpA, + struct bbs_Int16Arr* ptrA, + int16 valA ); + +#endif /* bbs_INT16ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Int32Arr.c b/Embedded/common/src/b_BasicEm/Int32Arr.c new file mode 100644 index 0000000..9326a7b --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Int32Arr.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Int32Arr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int32Arr_init( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int32Arr_exit( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int32Arr_copy( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + const struct bbs_Int32Arr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_Int32Arr_copy(...):\n" + "Unsufficient allocated memory in destination array." ); + return; + } +#endif + bbs_Int32Arr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy32( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE * bbs_SIZEOF32( int32 ) ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_Int32Arr_equal( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA, + const struct bbs_Int32Arr* srcPtrA ) +{ + uint32 iL; + const int32* ptr1L = ptrA->arrPtrE; + const int32* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( *ptr1L++ != *ptr2L++ ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int32Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA, + uint32 sizeA ) +{ + return sizeA * bbs_SIZEOF16( int32 ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int32Arr_create( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->sizeE == sizeA ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_Int32Arr_size( cpA, ptrA, sizeA ); + } + else + { + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( int32 ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeA; + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int32Arr_size( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_Int32Arr_size( struct bbs_Int32Arr*, uint32 ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int32Arr_memSize( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE * bbs_SIZEOF16( int32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int32Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_Int32Arr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite32Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int32Arr_memRead( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_Int32Arr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead32Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + + if( memSizeL != bbs_Int32Arr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_Int32Arr_memRead( const struct bbs_Int32Arr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int32Arr_fill( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + int32 valA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + ptrA->arrPtrE[ iL ] = valA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/Int32Arr.h b/Embedded/common/src/b_BasicEm/Int32Arr.h new file mode 100644 index 0000000..3ad2736 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Int32Arr.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_INT32ARR_EM_H +#define bbs_INT32ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** byte array */ +struct bbs_Int32Arr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of int32 */ + int32* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_Int32Arr */ +void bbs_Int32Arr_init( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA ); + +/** frees bbs_Int32Arr */ +void bbs_Int32Arr_exit( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_Int32Arr_copy( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + const struct bbs_Int32Arr* srcPtrA ); + +/** equal operator */ +flag bbs_Int32Arr_equal( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA, + const struct bbs_Int32Arr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_Int32Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bbs_Int32Arr */ +void bbs_Int32Arr_create( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_Int32Arr_size( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_Int32Arr_memSize( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bbs_Int32Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_Int32Arr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bbs_Int32Arr_memRead( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** fills array with a value */ +void bbs_Int32Arr_fill( struct bbs_Context* cpA, + struct bbs_Int32Arr* ptrA, + int32 valA ); + +#endif /* bbs_INT32ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Int8Arr.c b/Embedded/common/src/b_BasicEm/Int8Arr.c new file mode 100644 index 0000000..c31ceec --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Int8Arr.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Int8Arr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int8Arr_init( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int8Arr_exit( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int8Arr_copy( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + const struct bbs_Int8Arr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_Int8Arr_copy(...):\n" + "Unsufficient allocated memory in destination array." ); + return; + } +#endif + bbs_Int8Arr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy16( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE >> 1 ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_Int8Arr_equal( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA, + const struct bbs_Int8Arr* srcPtrA ) +{ + long iL; + const int8* ptr1L = ptrA->arrPtrE; + const int8* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( *ptr1L++ != *ptr2L++ ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int8Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA, + uint32 sizeA ) +{ + return ( sizeA >> 1 ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int8Arr_create( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->sizeE == sizeA ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_Int8Arr_size( cpA, ptrA, sizeA ); + } + else + { + /* if size is odd increase by 1 byte */ + uint32 sizeL = sizeA; + if( ( sizeL & 1 ) != 0 ) sizeL++; + + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeL >> 1 ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeL; + + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_Int8Arr_size( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_Int8Arr_size( struct bbs_Int8Arr*, uint32 ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int8Arr_memSize( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE / 2; /* int8 = 0.5 word size*/ +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int8Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_Int8Arr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE / 2, memPtrA ); + /*bbs_memcpy( memPtrA, ptrA->arrPtrE, ptrA->sizeE );*/ + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_Int8Arr_memRead( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_Int8Arr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE / 2, memPtrA ); + + if( memSizeL != bbs_Int8Arr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_Int8Arr_memRead( const struct bbs_Int8Arr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_Int8Arr_fill( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + int8 valA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + ptrA->arrPtrE[ iL ] = valA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/Int8Arr.h b/Embedded/common/src/b_BasicEm/Int8Arr.h new file mode 100644 index 0000000..1606657 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Int8Arr.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_INT8ARR_EM_H +#define bbs_INT8ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** byte array */ +struct bbs_Int8Arr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of int8 */ + int8* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_Int8Arr */ +void bbs_Int8Arr_init( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA ); + +/** frees bbs_Int8Arr */ +void bbs_Int8Arr_exit( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_Int8Arr_copy( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + const struct bbs_Int8Arr* srcPtrA ); + +/** equal operator */ +flag bbs_Int8Arr_equal( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA, + const struct bbs_Int8Arr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_Int8Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bbs_Int8Arr */ +void bbs_Int8Arr_create( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_Int8Arr_size( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_Int8Arr_memSize( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbs_Int8Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_Int8Arr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) written */ +uint32 bbs_Int8Arr_memRead( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** fills array with a value */ +void bbs_Int8Arr_fill( struct bbs_Context* cpA, + struct bbs_Int8Arr* ptrA, + int8 valA ); + +#endif /* bbs_INT8ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Math.c b/Embedded/common/src/b_BasicEm/Math.c new file mode 100644 index 0000000..a788beb --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Math.c @@ -0,0 +1,1282 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +#if defined( HW_SSE2 ) + extern int32 bbs_dotProduct_128SSE2( const int16* vec1A, const int16* vec2A, uint32 sizeA ); + extern int32 bbs_dotProduct_u128SSE2( const int16* vec1A, const int16* vec2A, uint32 sizeA ); +#endif + +#if defined( HW_FR71 ) + int32 bbs_dotProduct_fr71( const int16* vec1A, const int16* vec2A, uint32 sizeA ); +#endif + +/* ------------------------------------------------------------------------- */ + +uint16 bbs_sqrt32( uint32 valA ) +{ + uint32 rootL = 0; + uint32 expL = 0; + expL += ( ( valA >> ( expL + 0x10 ) ) != 0 ) << 4; + expL += ( ( valA >> ( expL + 0x08 ) ) != 0 ) << 3; + expL += ( ( valA >> ( expL + 0x04 ) ) != 0 ) << 2; + expL += ( ( valA >> ( expL + 0x02 ) ) != 0 ) << 1; + switch( expL >> 1 ) + { + case 15: rootL += ( ( rootL + 0x8000 ) * ( rootL + 0x8000 ) <= valA ) << 15; + case 14: rootL += ( ( rootL + 0x4000 ) * ( rootL + 0x4000 ) <= valA ) << 14; + case 13: rootL += ( ( rootL + 0x2000 ) * ( rootL + 0x2000 ) <= valA ) << 13; + case 12: rootL += ( ( rootL + 0x1000 ) * ( rootL + 0x1000 ) <= valA ) << 12; + case 11: rootL += ( ( rootL + 0x0800 ) * ( rootL + 0x0800 ) <= valA ) << 11; + case 10: rootL += ( ( rootL + 0x0400 ) * ( rootL + 0x0400 ) <= valA ) << 10; + case 9: rootL += ( ( rootL + 0x0200 ) * ( rootL + 0x0200 ) <= valA ) << 9; + case 8: rootL += ( ( rootL + 0x0100 ) * ( rootL + 0x0100 ) <= valA ) << 8; + case 7: rootL += ( ( rootL + 0x0080 ) * ( rootL + 0x0080 ) <= valA ) << 7; + case 6: rootL += ( ( rootL + 0x0040 ) * ( rootL + 0x0040 ) <= valA ) << 6; + case 5: rootL += ( ( rootL + 0x0020 ) * ( rootL + 0x0020 ) <= valA ) << 5; + case 4: rootL += ( ( rootL + 0x0010 ) * ( rootL + 0x0010 ) <= valA ) << 4; + case 3: rootL += ( ( rootL + 0x0008 ) * ( rootL + 0x0008 ) <= valA ) << 3; + case 2: rootL += ( ( rootL + 0x0004 ) * ( rootL + 0x0004 ) <= valA ) << 2; + case 1: rootL += ( ( rootL + 0x0002 ) * ( rootL + 0x0002 ) <= valA ) << 1; + case 0: rootL += ( ( rootL + 0x0001 ) * ( rootL + 0x0001 ) <= valA ) << 0; + } + + return ( uint16 )rootL; +} + +/* ------------------------------------------------------------------------- */ + +uint8 bbs_sqrt16( uint16 valA ) +{ + uint16 rootL = 0; + rootL += ( ( rootL + 0x80 ) * ( rootL + 0x80 ) <= valA ) << 7; + rootL += ( ( rootL + 0x40 ) * ( rootL + 0x40 ) <= valA ) << 6; + rootL += ( ( rootL + 0x20 ) * ( rootL + 0x20 ) <= valA ) << 5; + rootL += ( ( rootL + 0x10 ) * ( rootL + 0x10 ) <= valA ) << 4; + rootL += ( ( rootL + 0x08 ) * ( rootL + 0x08 ) <= valA ) << 3; + rootL += ( ( rootL + 0x04 ) * ( rootL + 0x04 ) <= valA ) << 2; + rootL += ( ( rootL + 0x02 ) * ( rootL + 0x02 ) <= valA ) << 1; + rootL += ( ( rootL + 0x01 ) * ( rootL + 0x01 ) <= valA ) << 0; + return ( uint8 )rootL; +} + +/* ------------------------------------------------------------------------- */ + +/* table of sqrt and slope values */ +const uint32 bbs_fastSqrt32_tableG[] = +{ + 268435456, 1016, 272596992, 1000, 276692992, 987, 280735744, 972, + 284717056, 959, 288645120, 946, 292519936, 933, 296341504, 922, + 300118016, 910, 303845376, 899, 307527680, 889, 311169024, 878, + 314765312, 869, 318324736, 858, 321839104, 850, 325320704, 840, + 328761344, 832, 332169216, 824, 335544320, 815, 338882560, 807, + 342188032, 799, 345460736, 792, 348704768, 785, 351920128, 777, + 355102720, 771, 358260736, 764, 361390080, 757, 364490752, 751, + 367566848, 745, 370618368, 739, 373645312, 732, 376643584, 727, + 379621376, 722, 382578688, 715, 385507328, 711, 388419584, 705, + 391307264, 700, 394174464, 695, 397021184, 689, 399843328, 686, + 402653184, 680, 405438464, 675, 408203264, 672, 410955776, 666, + 413683712, 663, 416399360, 658, 419094528, 653, 421769216, 650, + 424431616, 646, 427077632, 641, 429703168, 638, 432316416, 634, + 434913280, 630, 437493760, 627, 440061952, 622, 442609664, 620, + 445149184, 615, 447668224, 613, 450179072, 609, 452673536, 605, + 455151616, 602, 457617408, 600, 460075008, 595, 462512128, 593, + 464941056, 590, 467357696, 587, 469762048, 583, 472150016, 581, + 474529792, 578, 476897280, 575, 479252480, 572, 481595392, 569, + 483926016, 567, 486248448, 564, 488558592, 561, 490856448, 559, + 493146112, 556, 495423488, 553, 497688576, 552, 499949568, 548, + 502194176, 546, 504430592, 544, 506658816, 541, 508874752, 539, + 511082496, 537, 513282048, 534, 515469312, 533, 517652480, 529, + 519819264, 528, 521981952, 526, 524136448, 523, 526278656, 521, + 528412672, 519, 530538496, 517, 532656128, 515, 534765568, 514 +}; + +uint16 bbs_fastSqrt32( uint32 valA ) +{ + uint32 expL = 0; + uint32 valL; + uint32 offsL; + uint32 indexL = 0; + + if( valA == 0 ) return 0; + + /* compute closest even size exponent of valA */ + expL += ( ( valA >> ( expL + 0x10 ) ) != 0 ) << 4; + expL += ( ( valA >> ( expL + 0x08 ) ) != 0 ) << 3; + expL += ( ( valA >> ( expL + 0x04 ) ) != 0 ) << 2; + expL += ( ( valA >> ( expL + 0x02 ) ) != 0 ) << 1; + + valL = ( ( valA << ( 30 - expL ) ) - 1073741824 ); /* ( 1 << 30 ) */ + offsL = ( ( valL & 0x01FFFFFF ) + ( 1 << 12 ) ) >> 13; + indexL = ( valL >> 24 ) & 0xFE; + + return ( bbs_fastSqrt32_tableG[ indexL ] + offsL * bbs_fastSqrt32_tableG[ indexL + 1 ] ) >> ( 28 - ( expL >> 1 ) ); +} + +/* ------------------------------------------------------------------------- */ + +/* table of 1/sqrt (1.31) and negative slope (.15) values + referenced in b_GaborCueEm/focusDispAsm.s55, do not rename or remove ! */ +const uint32 bbs_invSqrt32_tableG[] = +{ + 2147483648u, 1001, 2114682880, 956, 2083356672, 915, 2053373952, 877, + 2024636416, 840, 1997111296, 808, 1970634752, 776, 1945206784, 746, + 1920761856, 720, 1897168896, 693, 1874460672, 669, 1852538880, 646, + 1831370752, 625, 1810890752, 604, 1791098880, 584, 1771962368, 567, + 1753382912, 548, 1735426048, 533, 1717960704, 516, 1701052416, 502, + 1684602880, 487, 1668644864, 474, 1653112832, 461, 1638006784, 448, + 1623326720, 436, 1609039872, 426, 1595080704, 414, 1581514752, 404, + 1568276480, 394, 1555365888, 384, 1542782976, 375, 1530494976, 367, + 1518469120, 357, 1506770944, 350, 1495302144, 342, 1484095488, 334, + 1473150976, 327, 1462435840, 320, 1451950080, 313, 1441693696, 307, + 1431633920, 300, 1421803520, 294, 1412169728, 289, 1402699776, 282, + 1393459200, 277, 1384382464, 272, 1375469568, 266, 1366753280, 262, + 1358168064, 257, 1349746688, 251, 1341521920, 248, 1333395456, 243, + 1325432832, 238, 1317634048, 235, 1309933568, 230, 1302396928, 227, + 1294958592, 222, 1287684096, 219, 1280507904, 216, 1273430016, 211, + 1266515968, 209, 1259667456, 205, 1252950016, 202, 1246330880, 198, + 1239842816, 196, 1233420288, 192, 1227128832, 190, 1220902912, 187, + 1214775296, 184, 1208745984, 181, 1202814976, 179, 1196949504, 176, + 1191182336, 173, 1185513472, 171, 1179910144, 169, 1174372352, 166, + 1168932864, 164, 1163558912, 162, 1158250496, 160, 1153007616, 157, + 1147863040, 155, 1142784000, 154, 1137737728, 151, 1132789760, 149, + 1127907328, 148, 1123057664, 145, 1118306304, 144, 1113587712, 142, + 1108934656, 140, 1104347136, 138, 1099825152, 137, 1095335936, 135, + 1090912256, 134, 1086521344, 131, 1082228736, 131, 1077936128, 128 +}; + +uint32 bbs_invSqrt32( uint32 valA ) +{ + + uint32 expL = 0; + uint32 valL; + uint32 offsL; + uint32 indexL = 0; + + if( valA == 0U ) return 0x80000000; + + /* compute closest even size exponent of valA */ + expL += ( ( valA >> ( expL + 0x10 ) ) != 0 ) << 4; + expL += ( ( valA >> ( expL + 0x08 ) ) != 0 ) << 3; + expL += ( ( valA >> ( expL + 0x04 ) ) != 0 ) << 2; + expL += ( ( valA >> ( expL + 0x02 ) ) != 0 ) << 1; + + valL = ( ( valA << ( 30 - expL ) ) - 1073741824 ); /* ( 1 << 30 ) */ + offsL = ( ( valL & 0x01FFFFFF ) + ( 1 << 9 ) ) >> 10; + indexL = ( valL >> 24 ) & 0xFE; + + return ( bbs_invSqrt32_tableG[ indexL ] - offsL * bbs_invSqrt32_tableG[ indexL + 1 ] ) >> ( expL >> 1 ); +} + +/* ------------------------------------------------------------------------- */ + +/* table of 1/( x + 1 ) (2.30) and negative slope (.14) values + referenced in b_GaborCueEm/focusDispAsm.s55, do not rename or remove ! */ +const int32 bbs_inv32_tableG[] = +{ + 1073741824, 1986, 1041203200, 1870, 1010565120, 1762, 981696512, 1664, + 954433536, 1575, 928628736, 1491, 904200192, 1415, 881016832, 1345, + 858980352, 1278, 838041600, 1218, 818085888, 1162, 799047680, 1108, + 780894208, 1059, 763543552, 1013, 746946560, 970, 731054080, 930, + 715816960, 891, 701218816, 856, 687194112, 823, 673710080, 791, + 660750336, 761, 648282112, 732, 636289024, 706, 624721920, 681, + 613564416, 657, 602800128, 635, 592396288, 613, 582352896, 592, + 572653568, 573, 563265536, 554, 554188800, 537, 545390592, 520, +}; + +int32 bbs_inv32( int32 valA ) +{ + + uint32 expL = 0; + int32 signL = ( ( valA >> 30 ) & 0xFFFFFFFE ) + 1; + int32 valL = signL * valA; + int32 offsL; + uint32 indexL = 0; + + if( valL <= ( int32 ) 1 ) return 0x40000000 * signL; + + /* compute size exponent of valL */ + expL += ( ( valL >> ( expL + 0x10 ) ) != 0 ) << 4; + expL += ( ( valL >> ( expL + 0x08 ) ) != 0 ) << 3; + expL += ( ( valL >> ( expL + 0x04 ) ) != 0 ) << 2; + expL += ( ( valL >> ( expL + 0x02 ) ) != 0 ) << 1; + expL += ( ( valL >> ( expL + 0x01 ) ) != 0 ); + + valL = ( ( valL << ( 30 - expL ) ) - 1073741824 ); /*( 1U << 30 )*/ + offsL = ( ( valL & 0x01FFFFFF ) + ( 1 << 10 ) ) >> 11; + indexL = ( valL >> 24 ) & 0xFE; + + return signL * ( ( ( ( bbs_inv32_tableG[ indexL ] - offsL * bbs_inv32_tableG[ indexL + 1 ] ) >> ( expL - 1 ) ) + 1 ) >> 1 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_intLog2( uint32 valA ) +{ + uint32 expL = 0; + expL += 0x10 * ( ( valA >> ( expL + 0x10 ) ) != 0 ); + expL += 0x08 * ( ( valA >> ( expL + 0x08 ) ) != 0 ); + expL += 0x04 * ( ( valA >> ( expL + 0x04 ) ) != 0 ); + expL += 0x02 * ( ( valA >> ( expL + 0x02 ) ) != 0 ); + expL += 0x01 * ( ( valA >> ( expL + 0x01 ) ) != 0 ); + return expL; +} + +/* ------------------------------------------------------------------------- */ + +const uint32 bbs_pow2M1_tableG[] = +{ + 0, 713, 46769127, 721, 94047537, 729, 141840775, 737, + 190154447, 745, 238994221, 753, 288365825, 761, 338275050, 769, + 388727751, 778, 439729846, 786, 491287318, 795, 543406214, 803, + 596092647, 812, 649352798, 821, 703192913, 830, 757619310, 839, + 812638371, 848, 868256550, 857, 924480371, 867, 981316430, 876, + 1038771393, 886, 1096851999, 895, 1155565062, 905, 1214917468, 915, + 1274916179, 925, 1335568233, 935, 1396880745, 945, 1458860907, 956, + 1521515988, 966, 1584853338, 976, 1648880387, 987, 1713604645, 998, + 1779033703, 1009, 1845175238, 1020, 1912037006, 1031, 1979626852, 1042, + 2047952702, 1053, 2117022572, 1065, 2186844564u, 1077, 2257426868u, 1088, + 2328777762u, 1100, 2400905617u, 1112, 2473818892u, 1124, 2547526141u, 1136, + 2622036010u, 1149, 2697357237u, 1161, 2773498659u, 1174, 2850469207u, 1187, + 2928277909u, 1200, 3006933892u, 1213, 3086446383u, 1226, 3166824708u, 1239, + 3248078296u, 1253, 3330216677u, 1266, 3413249486u, 1280, 3497186464u, 1294, + 3582037455u, 1308, 3667812413u, 1323, 3754521399u, 1337, 3842174584u, 1352, + 3930782250u, 1366, 4020354790u, 1381, 4110902710u, 1396, 4202436633u, 1411 +}; + +uint32 bbs_pow2M1( uint32 valA ) +{ + uint32 offsL = ( valA & 0x03FFFFFF ) >> 10; + uint16 indexL = ( ( valA & 0xFC000000 ) >> 26 ) << 1; + return bbs_pow2M1_tableG[ indexL ] + offsL * bbs_pow2M1_tableG[ indexL + 1 ]; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_pow2( int32 valA ) +{ + int32 shiftL = 16 - ( valA >> 27 ); + uint32 offsL = ( uint32 )( valA << 5 ); + if( shiftL == 32 ) return 1; + return ( 1 << ( 32 - shiftL ) ) + ( bbs_pow2M1( offsL ) >> shiftL ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_exp( int32 valA ) +{ + int32 adjustedL; + int32 shiftL; + int32 offsL; + + /* check boundaries to avoid overflow */ + if( valA < -1488522236 ) + { + return 0; + } + else if( valA > 1488522236 ) + { + return 0xFFFFFFFF; + } + + /* multily valA with 1/ln(2) in order to use function 2^x instead of e^x */ + adjustedL = ( valA >> 16 ) * 94548 + ( ( ( ( ( uint32 )valA ) & 0x0FFFF ) * 47274 ) >> 15 ); + + shiftL = 16 - ( adjustedL >> 27 ); + if( shiftL == 32 ) return 1; + offsL = ( uint32 )( adjustedL << 5 ); + return ( ( int32 ) 1 << ( 32 - shiftL ) ) + ( bbs_pow2M1( offsL ) >> shiftL ); +} + +/* ------------------------------------------------------------------------- */ + +int16 bbs_satS16( int32 valA ) +{ + if( valA > 32767 ) return 32767; + if( valA < -32768 ) return -32768; + return valA; +} + +/* ------------------------------------------------------------------------- */ + +#if defined( HW_i586 ) || defined( HW_i686 ) + +/* Windows section */ +#if defined( WIN32 ) && !defined( WIN64 ) + +/* disable warning "no return value"*/ +#pragma warning( disable : 4035 ) + +/** + * computes a fast dot product using intel MMX, sizeA must be multiple of 16 and >0 + */ +int32 bbs_dotProduct_intelMMX16( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + __asm + { + push esi + push edi + + mov eax, vec1A + mov ebx, vec2A + + mov ecx, sizeA + + pxor mm4, mm4 + pxor mm6, mm6 + + pxor mm7, mm7 + shr ecx, 4 + + inner_loop_start: + movq mm0, 0[eax] + paddd mm7, mm4 + + movq mm1, 0[ebx] + paddd mm7, mm6 + + movq mm2, 8[eax] + pmaddwd mm0, mm1 + + movq mm3, 8[ebx] + + movq mm4, 16[eax] + pmaddwd mm2, mm3 + + movq mm5, 16[ebx] + paddd mm7, mm0 + + movq mm6, 24[eax] + pmaddwd mm4, mm5 + + pmaddwd mm6, 24[ebx] + paddd mm7, mm2 + + add eax, 32 + add ebx, 32 + + dec ecx + jnz inner_loop_start + + paddd mm7, mm4 + + paddd mm7, mm6 + + movq mm0, mm7 + + psrlq mm0, 32 + + paddd mm7, mm0 + + movd eax, mm7 + + emms + pop edi + pop esi + } +} + +#pragma warning( default : 4035 ) + +/* gcc compiler section */ +#elif defined( epl_LINUX ) || defined( CYGWIN ) + +/** + * computes a fast dot product using intel MMX, sizeA must be multiple of 16 and >0 + */ +int32 bbs_dotProduct_intelMMX16( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + int32 resultL; + + __asm__ __volatile__( + + "movl %1,%%eax\n\t" + "movl %2,%%ebx\n\t" + + "movl %3,%%ecx\n\t" + + "pxor %%mm4,%%mm4\n\t" + "pxor %%mm6,%%mm6\n\t" + + "pxor %%mm7, %%mm7\n\t" + "shrl $4, %%ecx\n\t" + + "\n1:\t" + "movq 0(%%eax),%%mm0\n\t" + "paddd %%mm4,%%mm7\n\t" + + "movq 0( %%ebx ),%%mm1\n\t" + "paddd %%mm6,%%mm7\n\t" + + "movq 8( %%eax ),%%mm2\n\t" + "pmaddwd %%mm1,%%mm0\n\t" + + "movq 8( %%ebx ),%%mm3\n\t" + + "movq 16( %%eax ),%%mm4\n\t" + "pmaddwd %%mm3,%%mm2\n\t" + + "movq 16( %%ebx ),%%mm5\n\t" + "paddd %%mm0,%%mm7\n\t" + + "movq 24( %%eax ),%%mm6\n\t" + "pmaddwd %%mm5,%%mm4\n\t" + + "pmaddwd 24( %%ebx ),%%mm6\n\t" + "paddd %%mm2,%%mm7\n\t" + + "addl $32,%%eax\n\t" + "addl $32,%%ebx\n\t" + + "decl %%ecx\n\t" + "jnz 1b\n\t" + + "paddd %%mm4,%%mm7\n\t" + "paddd %%mm6,%%mm7\n\t" + + "movq %%mm7,%%mm0\n\t" + + "psrlq $32,%%mm0\n\t" + + "paddd %%mm0,%%mm7\n\t" + + "movd %%mm7,%0\n\t" + + "emms\n\t" + + : "=&g" ( resultL ) + : "g" ( vec1A ), "g" ( vec2A ), "g" ( sizeA ) + : "si", "di", "ax", "bx", "cx", "st", "memory" ); + + return resultL; +} + +#endif /* epl_LINUX, CYGWIN */ + +#endif /* HW_i586 || HW_i686 */ + +/* ------------------------------------------------------------------------- */ + +#ifdef HW_TMS320C6x +/** + * Calls fast assembler version of dotproduct for DSP. + * dotProduct_C62x is implemented in file dotprod.asm and expects input vectors + * of even length. + */ +int32 bbs_dotProduct_dsp( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + if( sizeA & 1 ) + { + int32 resultL; + resultL = dotProduct_C62x( vec1A, vec2A, sizeA - 1 ); + return resultL + ( int32 ) *( vec1A + sizeA - 1 ) * *( vec2A + sizeA - 1 ); + } + else + { + return dotProduct_C62x( vec1A, vec2A, sizeA ); + } +} +#endif /* HW_TMS320C6x */ + +/* ------------------------------------------------------------------------- */ + +/* 16 dot product for the PS2/EE processor */ +/* input vectors MUST be 128 bit aligned ! */ + +#if defined( epl_LINUX ) && defined( HW_EE ) + +int32 bbs_dotProduct_EE( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + int32 resultL = 0, + iL = sizeA >> 3, + jL = sizeA - ( iL << 3 ); + + if( iL > 0 ) + { + /* multiply-add elements of input vectors in sets of 8 */ + int32 accL[ 4 ], t1L, t2L, t3L; + asm volatile ( + "pxor %4, %2, %2\n\t" /* reset 8 accumulators (LO and HI register) to 0 */ + "pmtlo %4\n\t" + "pmthi %4\n\t" + + "\n__begin_loop:\t" + + "lq %2,0(%0)\n\t" /* load 8 pairs of int16 */ + "lq %3,0(%1)\n\t" + + "addi %0,%0,16\n\t" /* vec1L += 16 */ + "addi %1,%1,16\n\t" /* vec2L += 16 */ + "addi %7,%7,-1\n\t" /* iL-- */ + + "pmaddh %4,%2,%3\n\t" /* parallel multiply-add of 8 pairs of int16 */ + + "bgtzl %7,__begin_loop\n\t" /* if iL > 0 goto _begin_loop */ + + "pmflo %2\n\t" /* parallel add 8 accumulators , store remaining 4 accumulators in tmpL */ + "pmfhi %3\n\t" + "paddw %4,%2,%3\n\t" + "sq %4,0(%8)\n\t" + : "=r" ( vec1A ), "=r" ( vec2A ), "=r" ( t1L ), "=r" ( t2L ), "=r" ( t3L ) + : "0" ( vec1A ), "1" ( vec2A ), "r" ( iL ), "r" ( accL ) + : "memory" ); + + /* add 4 parallel accumulators */ + resultL += accL[ 0 ] + accL[ 1 ] + accL[ 2 ] + accL[ 3 ]; + } + + /* multiply-add remaining elements of input vectors */ + for( ; jL--; ) resultL += ( int32 ) *vec1A++ * *vec2A++; + + return resultL; +} + +#endif + +/* ------------------------------------------------------------------------- */ + +#if defined( HW_ARMv5TE ) + +/* fast 16 dot product for ARM9E cores (DSP extensions). + * input vectors must be 32 bit aligned + */ +int32 bbs_dotProduct_arm9e( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + int32 accuL = 0; + + int32* v1PtrL = ( int32* )vec1A; + int32* v2PtrL = ( int32* )vec2A; + + for( ; sizeA >= 4; sizeA -= 4 ) + { + __asm { + smlabb accuL, *v1PtrL, *v2PtrL, accuL; + smlatt accuL, *v1PtrL, *v2PtrL, accuL; + } + v1PtrL++; v2PtrL++; + __asm { + smlabb accuL, *v1PtrL, *v2PtrL, accuL; + smlatt accuL, *v1PtrL, *v2PtrL, accuL; + } + v1PtrL++; v2PtrL++; + } + + vec1A = ( int16* )v1PtrL; + vec2A = ( int16* )v2PtrL; + + /* multiply-add remaining elements of input vectors */ + for( ; sizeA > 0; sizeA-- ) accuL += ( int32 )*vec1A++ * *vec2A++; + + return accuL; +} + +#endif + +/* ------------------------------------------------------------------------- */ + +/** + * Computes a fast dot product using standard C + */ +int32 bbs_dotProduct_stdc( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + int32 accuL = 0; + + for( ; sizeA >= 8; sizeA -= 8 ) + { + accuL += ( int32 ) *vec1A * *vec2A; + accuL += ( int32 ) *( vec1A + 1 ) * *( vec2A + 1 ); + accuL += ( int32 ) *( vec1A + 2 ) * *( vec2A + 2 ); + accuL += ( int32 ) *( vec1A + 3 ) * *( vec2A + 3 ); + + accuL += ( int32 ) *( vec1A + 4 ) * *( vec2A + 4 ); + accuL += ( int32 ) *( vec1A + 5 ) * *( vec2A + 5 ); + accuL += ( int32 ) *( vec1A + 6 ) * *( vec2A + 6 ); + accuL += ( int32 ) *( vec1A + 7 ) * *( vec2A + 7 ); + + vec1A += 8; + vec2A += 8; + } + + for( ; sizeA; sizeA-- ) accuL += ( int32 ) *vec1A++ * *vec2A++; + + return accuL; +} + +/* ------------------------------------------------------------------------- */ + +int32 bbs_dotProductInt16( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ +/* PC */ +#if ( defined( HW_i586 ) || defined( HW_i686 ) ) + + #if defined( HW_SSE2 ) + uint32 size16L = sizeA & 0xfffffff0; + if( size16L ) + { + if( ( (uint32)vec1A & 0xF ) == 0 && ( (uint32)vec2A & 0xF ) == 0 ) + { + return bbs_dotProduct_128SSE2( vec1A, vec2A, sizeA ); + } + else + { + return bbs_dotProduct_u128SSE2( vec1A, vec2A, sizeA ); + } + } + #elif !defined( WIN64 ) + /* MMX version (not supported by 64-bit compiler) */ + uint32 size16L = sizeA & 0xfffffff0; + if( size16L ) + { + if( sizeA == size16L ) + { + return bbs_dotProduct_intelMMX16( vec1A, vec2A, size16L ); + } + return bbs_dotProduct_intelMMX16( vec1A, vec2A, size16L ) + + bbs_dotProduct_stdc( vec1A + size16L, vec2A + size16L, sizeA - size16L ); + } /* if( size16L ) */ + #endif + + return bbs_dotProduct_stdc( vec1A, vec2A, sizeA ); + +/* Playstation 2 */ +#elif defined( HW_EE ) && defined( epl_LINUX ) + + if( ( (uint32)vec1A & 0xF ) == 0 && ( (uint32)vec2A & 0xF ) == 0 ) + { + return bbs_dotProduct_EE( vec1A, vec2A, sizeA ); + } + return bbs_dotProduct_stdc( vec1A, vec2A, sizeA ); + +/* ARM9E */ +#elif defined( HW_ARMv5TE ) + + return bbs_dotProduct_arm9e( vec1A, vec2A, sizeA ); + +/* TI C6000 */ +#elif defined( HW_TMS320C6x ) + + return bbs_dotProduct_dsp( vec1A, vec2A, sizeA ); + +#elif defined( HW_FR71 ) + + uint32 size16L = sizeA & 0xfffffff0; + if( size16L ) + { + if( sizeA == size16L ) + { + return bbs_dotProduct_fr71( vec1A, vec2A, size16L ); + } + return bbs_dotProduct_fr71( vec1A, vec2A, size16L ) + + bbs_dotProduct_stdc( vec1A + size16L, vec2A + size16L, sizeA - size16L ); + } + + return bbs_dotProduct_stdc( vec1A, vec2A, sizeA ); + +#endif + + return bbs_dotProduct_stdc( vec1A, vec2A, sizeA ); +} + +/* ------------------------------------------------------------------------- */ + +/* table of fermi and slope values (result: 2.30; offset: .12) + referenced in b_NeuralNetEm/FastMlpNet.c, not not rename or remove */ +const uint32 bbs_fermi_tableG[] = +{ + 45056, 8, 77824, 13, 131072, 21, 217088, 34, + 356352, 57, 589824, 94, 974848, 155, 1609728, 255, + 2654208, 418, 4366336, 688, 7184384, 1126, 11796480, 1834, + 19308544, 2970, 31473664, 4748, 50921472, 7453, 81448960, 11363, + 127991808, 16573, 195874816, 22680, 288772096, 28469, 405381120, 32102, + 536870912, 32101, 668356608, 28469, 784965632, 22680, 877862912, 16573, + 945745920, 11363, 992288768, 7453, 1022816256, 4748, 1042264064, 2970, + 1054429184, 1834, 1061941248, 1126, 1066553344, 688, 1069371392, 418, + 1071083520, 255, 1072128000, 155, 1072762880, 94, 1073147904, 57, + 1073381376, 34, 1073520640, 21, 1073606656, 13, 1073659904, 8, +}; + +int32 bbs_fermi( int32 valA ) +{ + uint32 indexL = ( ( valA >> 15 ) + 20 ) << 1; + uint32 offsL = ( ( valA & 0x00007FFF ) + 4 ) >> 3; + if( valA < -655360 ) return 1; + if( valA >= 655360 ) return 1073741824 - 1; /* ( 1 << 30 ) */ + return ( bbs_fermi_tableG[ indexL ] + offsL * bbs_fermi_tableG[ indexL + 1 ] ); +} + +/* ------------------------------------------------------------------------- */ + +void bbs_uint32ReduceToNBits( uint32* argPtrA, int32* bbpPtrA, uint32 nBitsA ) +{ + int32 posHighestBitL = bbs_intLog2( *argPtrA ) + 1; + int32 shiftL = posHighestBitL - nBitsA; + if( shiftL > 0 ) + { + ( *argPtrA ) >>= shiftL; + ( *bbpPtrA ) -= shiftL; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_int32ReduceToNBits( int32* argPtrA, int32* bbpPtrA, uint32 nBitsA ) +{ + int32 posHighestBitL = bbs_intLog2( bbs_abs( *argPtrA ) ) + 1; + int32 shiftL = posHighestBitL - nBitsA; + if( shiftL > 0 ) + { + ( *argPtrA ) >>= shiftL; + ( *bbpPtrA ) -= shiftL; + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_convertU32( uint32 srcA, int32 srcBbpA, int32 dstBbpA ) +{ + if( dstBbpA >= srcBbpA ) + { + uint32 shiftL = dstBbpA - srcBbpA; + if( srcA > ( ( uint32 )0xFFFFFFFF >> shiftL ) ) + { + /* overflow */ + return ( uint32 )0xFFFFFFFF; + } + else + { + return srcA << shiftL; + } + } + else + { + uint32 shiftL = srcBbpA - dstBbpA; + uint32 addL = 1L << ( shiftL - 1 ); + if( srcA + addL < addL ) + { + /* rounding would cause overflow */ + return srcA >> shiftL; + } + else + { + return ( srcA + addL ) >> shiftL; + } + } +} + +/* ------------------------------------------------------------------------- */ + +int32 bbs_convertS32( int32 srcA, int32 srcBbpA, int32 dstBbpA ) +{ + if( dstBbpA >= srcBbpA ) + { + uint32 shiftL = ( uint32 )( dstBbpA - srcBbpA ); + if( srcA > ( ( int32 )0x7FFFFFFF >> shiftL ) ) + { + /* overflow */ + return ( uint32 )0x7FFFFFFF; + } + else if( srcA < ( ( int32 )0x80000000 >> shiftL ) ) + { + /* underflow */ + return ( int32 )0x80000000; + } + else + { + return srcA << shiftL; + } + } + else + { + uint32 shiftL = ( uint32 )( srcBbpA - dstBbpA ); + int32 addL = 1L << ( shiftL - 1 ); + if( srcA + addL < addL ) + { + /* rounding would cause overflow */ + return srcA >> shiftL; + } + else + { + return ( srcA + addL ) >> shiftL; + } + } +} + +/* ------------------------------------------------------------------------- */ + +int32 bbs_vecPowerFlt16( const int16 *xA, int16 nxA ) +{ +/* #if defined( HW_TMS320C5x ) + uint32 rL; + power( ( int16* ) xA, ( int32* ) &rL, nxA ); // does not work properly in DSPLib version 2.20.02 + return ( rL >> 1 ); + #else*/ + /* needs to be optimized */ + int32 rL = 0; + for( ; nxA--; ) + { + rL += ( int32 ) *xA * *xA; + xA++; + } + return rL; +/* #endif */ +} + +/* ------------------------------------------------------------------------- */ + +void bbs_mulU32( uint32 v1A, uint32 v2A, uint32* manPtrA, int32* expPtrA ) +{ + uint32 log1L = bbs_intLog2( v1A ); + uint32 log2L = bbs_intLog2( v2A ); + + if( log1L + log2L < 32 ) + { + *manPtrA = v1A * v2A; + *expPtrA = 0; + } + else + { + uint32 v1L = v1A; + uint32 v2L = v2A; + uint32 exp1L = 0; + uint32 exp2L = 0; + if( log1L > 15 && log2L > 15 ) + { + exp1L = log1L - 15; + exp2L = log2L - 15; + v1L = ( ( v1L >> ( exp1L - 1 ) ) + 1 ) >> 1; + v2L = ( ( v2L >> ( exp2L - 1 ) ) + 1 ) >> 1; + } + else if( log1L > 15 ) + { + exp1L = log1L + log2L - 31; + v1L = ( ( v1L >> ( exp1L - 1 ) ) + 1 ) >> 1; + } + else + { + exp2L = log1L + log2L - 31; + v2L = ( ( v2L >> ( exp2L - 1 ) ) + 1 ) >> 1; + } + + *manPtrA = v1L * v2L; + *expPtrA = exp1L + exp2L; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_mulS32( int32 v1A, int32 v2A, int32* manPtrA, int32* expPtrA ) +{ + uint32 log1L = bbs_intLog2( v1A > 0 ? v1A : -v1A ); + uint32 log2L = bbs_intLog2( v2A > 0 ? v2A : -v2A ); + + if( log1L + log2L < 30 ) + { + *manPtrA = v1A * v2A; + *expPtrA = 0; + } + else + { + int32 v1L = v1A; + int32 v2L = v2A; + int32 exp1L = 0; + int32 exp2L = 0; + if( log1L > 14 && log2L > 14 ) + { + exp1L = log1L - 14; + exp2L = log2L - 14; + v1L = ( ( v1L >> ( exp1L - 1 ) ) + 1 ) >> 1; + v2L = ( ( v2L >> ( exp2L - 1 ) ) + 1 ) >> 1; + } + else if( log1L > 14 ) + { + exp1L = log1L + log2L - 29; + v1L = ( ( v1L >> ( exp1L - 1 ) ) + 1 ) >> 1; + } + else + { + exp2L = log1L + log2L - 29; + v2L = ( ( v2L >> ( exp2L - 1 ) ) + 1 ) >> 1; + } + + *manPtrA = v1L * v2L; + *expPtrA = exp1L + exp2L; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_vecSqrNorm32( const int32* vecA, uint32 sizeA, uint32* manPtrA, uint32* expPtrA ) +{ + uint32 sumL = 0; + int32 sumExpL = 0; + + uint32 iL; + for( iL = 0; iL < sizeA; iL++ ) + { + int32 vL = vecA[ iL ]; + int32 logL = bbs_intLog2( vL > 0 ? vL : -vL ); + int32 expL = ( logL > 14 ) ? logL - 14 : 0; + uint32 prdL; + + if( expL >= 1 ) + { + vL = ( ( vL >> ( expL - 1 ) ) + 1 ) >> 1; + } + else + { + vL = vL >> expL; + } + + prdL = vL * vL; + expL <<= 1; /* now exponent of product */ + + if( sumExpL > expL ) + { + uint32 shrL = sumExpL - expL; + prdL = ( ( prdL >> ( shrL - 1 ) ) + 1 ) >> 1; + } + else if( expL > sumExpL ) + { + uint32 shrL = expL - sumExpL; + sumL = ( ( sumL >> ( shrL - 1 ) ) + 1 ) >> 1; + sumExpL += shrL; + } + + sumL += prdL; + + if( sumL > 0x80000000 ) + { + sumL = ( sumL + 1 ) >> 1; + sumExpL++; + } + } + + /* make exponent even */ + if( ( sumExpL & 1 ) != 0 ) + { + sumL = ( sumL + 1 ) >> 1; + sumExpL++; + } + + if( manPtrA != NULL ) *manPtrA = sumL; + if( expPtrA != NULL ) *expPtrA = sumExpL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_vecSqrNorm16( const int16* vecA, uint32 sizeA, uint32* manPtrA, uint32* expPtrA ) +{ + uint32 sumL = 0; + int32 sumExpL = 0; + + uint32 iL; + for( iL = 0; iL < sizeA; iL++ ) + { + int32 vL = vecA[ iL ]; + uint32 prdL = vL * vL; + + if( sumExpL > 0 ) + { + uint32 shrL = sumExpL; + prdL = ( ( prdL >> ( shrL - 1 ) ) + 1 ) >> 1; + } + + sumL += prdL; + + if( sumL > 0x80000000 ) + { + sumL = ( sumL + 1 ) >> 1; + sumExpL++; + } + } + + /* make exponent even */ + if( ( sumExpL & 1 ) != 0 ) + { + sumL = ( sumL + 1 ) >> 1; + sumExpL++; + } + + if( manPtrA != NULL ) *manPtrA = sumL; + if( expPtrA != NULL ) *expPtrA = sumExpL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_vecNorm16( const int16* vecA, uint32 sizeA ) +{ + uint32 manL; + uint32 expL; + bbs_vecSqrNorm16( vecA, sizeA, &manL, &expL ); + manL = bbs_sqrt32( manL ); + return manL << ( expL >> 1 ); +} + +/* ------------------------------------------------------------------------- */ + +void bbs_matMultiplyFlt16( const int16 *x1A, int16 row1A, int16 col1A, const int16 *x2A, int16 col2A, int16 *rA ) +{ + #if defined( HW_TMS320C5x ) + /* operands need to be in internal memory for mmul*/ + if( x1A > ( int16* ) bbs_C5X_INTERNAL_MEMORY_SIZE || + x2A > ( int16* ) bbs_C5X_INTERNAL_MEMORY_SIZE ) + { + int16 iL,jL,kL; + int16 *ptr1L, *ptr2L; + int32 sumL; + + for( iL = 0; iL < row1A; iL++ ) + { + for( jL = 0; jL < col2A; jL++ ) + { + ptr1L = ( int16* ) x1A + iL * col1A; + ptr2L = ( int16* ) x2A + jL; + sumL = 0; + for( kL = 0; kL < col1A; kL++ ) + { + sumL += ( ( int32 ) *ptr1L++ * *ptr2L ); + ptr2L += col2A; + } + *rA++ = ( sumL + ( 1 << 14 ) ) >> 15; /* round result to 1.15 */ + } + } + } + else mmul( ( int16* ) x1A, row1A, col1A, ( int16* ) x2A, col1A, col2A, rA ); + + #elif defined( HW_ARMv4 ) || defined( HW_ARMv5TE ) + + int32 iL, jL, kL; + int16 *ptr1L, *ptr2L; + int32 sumL; + for( iL = 0; iL < row1A; iL++ ) + { + for( jL = 0; jL < col2A; jL++ ) + { + ptr1L = ( int16* ) x1A + iL * col1A; + ptr2L = ( int16* ) x2A + jL; + sumL = 0; + for( kL = col1A; kL >= 4; kL -= 4 ) + { + sumL += ( ( int32 ) *ptr1L++ * *ptr2L ); + sumL += ( ( int32 ) *ptr1L++ * *( ptr2L += col2A ) ); + sumL += ( ( int32 ) *ptr1L++ * *( ptr2L += col2A ) ); + sumL += ( ( int32 ) *ptr1L++ * *( ptr2L += col2A ) ); + ptr2L += col2A; + } + for( ; kL > 0; kL-- ) + { + sumL += ( ( int32 ) *ptr1L++ * *ptr2L ); + ptr2L += col2A; + } + *rA++ = ( sumL + ( 1 << 14 ) ) >> 15; /* round result to 1.15 */ + } + } + #else + /* needs to be optimized */ + int16 iL,jL,kL; + int16 *ptr1L, *ptr2L; + int32 sumL; + + for( iL = 0; iL < row1A; iL++ ) + { + for( jL = 0; jL < col2A; jL++ ) + { + ptr1L = ( int16* ) x1A + iL * col1A; + ptr2L = ( int16* ) x2A + jL; + sumL = 0; + for( kL = 0; kL < col1A; kL++ ) + { + sumL += ( ( int32 ) *ptr1L++ * *ptr2L ); + ptr2L += col2A; + } + *rA++ = ( sumL + ( 1 << 14 ) ) >> 15; /* round result to 1.15 */ + } + } + #endif +} + +/* ------------------------------------------------------------------------- */ + +void bbs_matMultiplyTranspFlt16( const int16 *x1A, int16 row1A, int16 col1A, + const int16 *x2A, int16 col2A, int16 *rA ) +{ + const int16* ptr1L = x1A; + + int32 iL; + for( iL = row1A; iL > 0 ; iL-- ) + { + int32 jL; + const int16* ptr2L = x2A; + for( jL = col2A; jL > 0 ; jL-- ) + { + int32 kL; + int32 sumL = 0; + for( kL = col1A >> 2; kL > 0; kL-- ) + { + sumL += ( ( int32 ) *ptr1L++ * *ptr2L++ ); + sumL += ( ( int32 ) *ptr1L++ * *ptr2L++ ); + sumL += ( ( int32 ) *ptr1L++ * *ptr2L++ ); + sumL += ( ( int32 ) *ptr1L++ * *ptr2L++ ); + } + for( kL = col1A & 3; kL > 0; kL-- ) + { + sumL += ( ( int32 ) *ptr1L++ * *ptr2L++ ); + } + *rA++ = ( sumL + ( 1 << 14 ) ) >> 15; /* round result to 1.15 */ + ptr1L -= col1A; + } + ptr1L += col1A; + } +} + +/* ------------------------------------------------------------------------- */ + + +#ifndef mtrans +uint16 bbs_matTrans( int16 *xA, int16 rowA, int16 colA, int16 *rA ) +{ + /* needs to be optimized */ + int16 iL; + for( iL = colA; iL--; ) + { + int16* sL = xA++; + int16 jL; + for( jL = rowA; jL--; ) + { + *rA++ = *sL; + sL += colA; + } + } + return 0; +} +#endif + +/* ------------------------------------------------------------------------- */ +#ifndef atan2_16 +int16 bbs_atan2( int16 nomA, int16 denomA ) +{ + int16 phL, argL; + + if( nomA == denomA ) return 8192; + argL = ( ( int32 ) nomA << 15 ) / denomA; + + /* 0.318253*2 x 20857 .15 + +0.003314*2 x^2 217 .15 + -0.130908*2 x^3 -8580 .15 + +0.068542*2 x^4 4491 .15 + -0.009159*2 x^5 -600 .15 */ + + phL = -600; + phL = ( ( ( int32 ) phL * argL ) >> 15 ) + 4481; + phL = ( ( ( int32 ) phL * argL ) >> 15 ) - 8580; + phL = ( ( ( int32 ) phL * argL ) >> 15 ) + 217; + phL = ( ( ( int32 ) phL * argL ) >> 15 ) + 20857; + phL = ( ( int32 ) phL * argL ) >> 15; + + return phL >> 1; /* /2 */ +} + +/* needs to be optimized */ +uint16 bbs_vecPhase( int16 *reA, int16 *imA, int16 *phaseA, uint16 sizeA ) +{ + for( ; sizeA--; ) + { + int16 reL = *reA++; + int16 imL = *imA++; + int16 phL = 0; + + if( reL < 0 ) + { + reL = -reL; + if( imL < 0 ) + { + imL = -imL; + if( reL > imL ) + { + phL = -32768 + bbs_atan2( imL, reL ); + } + else + { + phL = -16384 - bbs_atan2( reL, imL ); + } + } + else + { + if( reL > imL ) + { + phL = -( -32768 + bbs_atan2( imL, reL ) ); + } + else + { + if( imL == 0 ) phL = 0; + else phL = 16384 + bbs_atan2( reL, imL ); + } + } + } + else + { + if( imL < 0 ) + { + imL = -imL; + if( reL > imL ) + { + phL = -bbs_atan2( imL, reL ); + } + else + { + phL = -16384 + bbs_atan2( reL, imL ); + } + } + else + { + if( reL > imL ) + { + phL = bbs_atan2( imL, reL ); + } + else + { + if( imL == 0 ) phL = 0; + else phL = 16384 - bbs_atan2( reL, imL ); + } + } + } + + *phaseA++ = phL; + } + return 0; +} + +#endif + +/* ------------------------------------------------------------------------- */ diff --git a/Embedded/common/src/b_BasicEm/Math.h b/Embedded/common/src/b_BasicEm/Math.h new file mode 100644 index 0000000..e492b22 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Math.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_MATH_EM_H +#define bbs_MATH_EM_H + +/** + * This files contains mathematical functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#ifdef HW_TMS320C5x +#include "Dsplib.h" +#endif + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- macros ------------------------------------------------------------- */ + +/** computes the maximum of two variables */ +#define bbs_max( val1A, val2A ) ( ( val1A ) > ( val2A ) ? ( val1A ) : ( val2A ) ) + +/** computes the minimum of two variables */ +#define bbs_min( val1A, val2A ) ( ( val1A ) < ( val2A ) ? ( val1A ) : ( val2A ) ) + +/** computes the absolute value */ +#define bbs_abs( valA ) ( ( valA ) > 0 ? ( valA ) : -( valA ) ) + +/* ---- external functions ------------------------------------------------- */ + +/** + * Computes square root from 32 bit value. + * The return value 'r' is the largest possible integer that + * satisfies r * r <= valA. + * This behavior is identical with (uint16)sqrt( valA ). + * C6201: 162 cycles + */ +uint16 bbs_sqrt32( uint32 valA ); + +/** + * Computes square root from 16 bit value. + * The return value 'r' is the largest possible integer that + * satisfies r * r <= valA. + * This behavior is identical with (uint8)sqrt( valA ). + */ +uint8 bbs_sqrt16( uint16 valA ); + +/** Sqrt approximation */ +uint16 bbs_fastSqrt32( uint32 valA ); + +/** sqrt(1/x) approximation + * return format 1.31 + */ +uint32 bbs_invSqrt32( uint32 valA ); + +/** 1/x approximation + * return format 2.30 + */ +int32 bbs_inv32( int32 valA ); + +/** Returns integer log2 of valA + * C6201: 24 cycles + */ +uint32 bbs_intLog2( uint32 valA ); + +/** + * Returns (2^x) - 1 for a value range of [0,1[ + * Format of valA: 0.32 + * Format of return value: 0.32 + */ +uint32 bbs_pow2M1( uint32 valA ); + +/** + * Returns (2^x) for a value range of [-16,16[ + * Format of valA: 5.27 + * Format of return value: 16.16 + */ +uint32 bbs_pow2( int32 valA ); + + +/** + * Returns (e^x) for a value range of [-11.0903,11.0903] + * If valA is smaller than -11.0903, the function returns 0 + * If valA is larger than 11.0903, the function returns ( 2^32 - 1 ) / ( 2^16 ) + * Format of valA: 5.27 + * Format of return value: 16.16 + * C6201: 72 cycles + */ +uint32 bbs_exp( int32 valA ); + +/** saturates a signed 32 bit value to signed 16 bit */ +int16 bbs_satS16( int32 valA ); + +/** + * Returns the value after rounding to the nearest integer. + */ +/* int32 bbs_round( int32 valA, int32 bbpA ); */ + +/** + * Computes the dot product of vec1A with vec2A, both of size sizeA. + * (no overflow handling, slow for sizeA < 32 ) + */ +int32 bbs_dotProductInt16( const int16* vec1A, const int16* vec2A, uint32 sizeA ); + +/** Fermi function ( 1.0 / ( 1.0 + exp( -valA ) ) ) + * Format valA: 16.16 + * Format return: 2.30 + */ +int32 bbs_fermi( int32 valA ); + +/** reduces uint32 to N bits; if it has already <= N bits, nothing happens */ +void bbs_uint32ReduceToNBits( uint32* argPtrA, int32* bbpPtrA, uint32 nBitsA ); + +/** reduces int32 to N bits; if it has already <= N bits, nothing happens */ +void bbs_int32ReduceToNBits( int32* argPtrA, int32* bbpPtrA, uint32 nBitsA ); + +/** converts a number with source bbp to a 32 bit number with dst bbp; + * applies appropriate shifting, rounding and saturation to minimize overflow-damage + */ +uint32 bbs_convertU32( uint32 srcA, int32 srcBbpA, int32 dstBbpA ); + +/** converts a number with source bbp to a 32 bit number with dst bbp; + * applies appropriate shifting, rounding and saturation to minimize overflow-damage + */ +int32 bbs_convertS32( int32 srcA, int32 srcBbpA, int32 dstBbpA ); + +/** vector power return val = sum(xA_i^2), input 1.15, output 1.30 */ +int32 bbs_vecPowerFlt16( const int16 *xA, int16 nxA ); + +/** returns floating point squared norm of 32 bit vector (maximum accuracy - overflow-safe); + * Function is slow + * returned square norm = man * 2^exp + * The returned exponent is always even + */ +void bbs_vecSqrNorm32( const int32* vecA, uint32 sizeA, uint32* manPtrA, uint32* expPtrA ); + +/** returns floating point squared norm of 16 bit vector (maximum accuracy - overflow-safe); + * returned square norm = man * 2^exp + * The returned exponent is always even + */ +void bbs_vecSqrNorm16( const int16* vecA, uint32 sizeA, uint32* manPtrA, uint32* expPtrA ); + +/** returns the norm of a 16 bit vector; + * overflow-safe when sizeA < 65535 + */ +uint32 bbs_vecNorm16( const int16* vecA, uint32 sizeA ); + +/** multiplies two unsigned 32 bit values and returns product decomposed to mantisse and exponent + * maximum accuracy - overflow-safe + * exponent is always >= 0 + */ +void bbs_mulU32( uint32 v1A, uint32 v2A, uint32* manPtrA, int32* expPtrA ); + +/** multiplies two signed 32 bit values and returns product decomposed to mantisse and exponent + * maximum accuracy - overflow-safe + * exponent is always >= 0 + */ +void bbs_mulS32( int32 v1A, int32 v2A, int32* manPtrA, int32* expPtrA ); + +/** matrix multiply rA = x1A * x2A, input/output 1.15, no overflow protection, in-place not allowed */ +void bbs_matMultiplyFlt16( const int16 *x1A, int16 row1A, int16 col1A, + const int16 *x2A, int16 col2A, int16 *rA ); + +/** matrix multiply rA = x1A * transposed( x2A ), input/output 1.15, no overflow protection, in-place not allowed */ +void bbs_matMultiplyTranspFlt16( const int16 *x1A, int16 row1A, int16 col1A, + const int16 *x2A, int16 row2A, int16 *rA ); + +/* +#ifdef mtrans +#define bbs_matTrans mtrans +#else +uint16 bbs_matTrans( int16 *xA, int16 rowA, int16 colA, int16 *rA ); +#endif + +#ifdef atan2_16 +#define bbs_vecPhase atan2_16 +#else +uint16 bbs_vecPhase( int16* reA, int16* imA, int16* phaseA, uint16 sizeA ); +#endif +*/ + +#endif /* bbs_MATH_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/MathSSE2.c b/Embedded/common/src/b_BasicEm/MathSSE2.c new file mode 100644 index 0000000..236d8bc --- /dev/null +++ b/Embedded/common/src/b_BasicEm/MathSSE2.c @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" /* to disable some warnings in VC++ */ + +#if ( defined( WIN64 ) || defined( HW_SSE2 ) ) + +#include "emmintrin.h" + +/* disable warning "local variable 'x' used without having been initialized" */ +#pragma warning( disable : 4700 ) + + +/** Using half register (64-bit) in SSE2 to calculate dot product. + * This is a SSE2 reimplementation of bbs_dotProduct_intelMMX16 in Math.c. + * Dependencies: input vectors need to be 16-bit aligned + * Return Value: int32 containing resultL of dot product + */ +int32 bbs_dotProduct_64SSE2( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + __m128i m_XMM0, m_XMM1, m_XMM2, m_XMM3, m_XMM4, m_XMM5, m_XMM6, m_XMM7, m_XMM8; + int16* vec1L = ( int16* )vec1A; + int16* vec2L = ( int16* )vec2A; + + int32 resultL = 0; + uint32 alignOffSetL = 0; + + /* initialize registers to 0 */ + m_XMM4 = _mm_xor_si128( m_XMM4, m_XMM4 ); + m_XMM6 = _mm_xor_si128( m_XMM6, m_XMM6 ); + m_XMM7 = _mm_xor_si128( m_XMM7, m_XMM7 ); + + alignOffSetL = sizeA % 16; + sizeA >>= 4; + + if( sizeA ) + { + while( sizeA > 0 ) + { + m_XMM0 = _mm_loadl_epi64( (__m128i *)&0[vec1L] ); + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM4 ); + + m_XMM1 = _mm_loadl_epi64( (__m128i *)&0[vec2L] ); + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM6 ); + + m_XMM2 = _mm_loadl_epi64( (__m128i *)&4[vec1L] ); + + m_XMM0 = _mm_madd_epi16( m_XMM0, m_XMM1 ); + + m_XMM3 = _mm_loadl_epi64( (__m128i *)&4[vec2L] ); + m_XMM4 = _mm_loadl_epi64( (__m128i *)&8[vec1L] ); + + m_XMM2 = _mm_madd_epi16( m_XMM2, m_XMM3 ); + + m_XMM5 = _mm_loadl_epi64( (__m128i *)&8[vec2L] ); + + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM0 ); + + m_XMM6 = _mm_loadl_epi64( (__m128i *)&12[vec1L] ); + + m_XMM4 = _mm_madd_epi16( m_XMM4, m_XMM5 ); + + m_XMM8 = _mm_loadl_epi64( (__m128i *)&12[vec2L] ); + m_XMM6 = _mm_madd_epi16( m_XMM6, m_XMM8 ); + + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM2 ); + + vec1L += 16; + vec2L += 16; + sizeA--; + } + + /* sum up accumulators */ + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM4 ); + + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM6 ); + + m_XMM0 = _mm_loadl_epi64( (__m128i *)&m_XMM7 ); + + m_XMM0 = _mm_srli_epi64( m_XMM0, 32 ); + + m_XMM7 = _mm_add_epi32( m_XMM7, m_XMM0 ); + + resultL = _mm_cvtsi128_si32( m_XMM7 ); + } + + /* switch statements produces faster code than loop */ + switch( alignOffSetL ) + { + case 15: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 14: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 13: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 12: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 11: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 10: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 9: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 8: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 7: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 6: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 5: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 4: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 3: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 2: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 1: + resultL += ( int32 )*vec1L++ * *vec2L++; + } + + return resultL; +} + +/* ------------------------------------------------------------------------- */ + +/** Using full register (128-bit) in SSE2 to calculate dot Product. + * Dependencies: 16-bit aligned + * Return Value: int32 containing dot Product + */ +int32 bbs_dotProduct_128SSE2( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + __m128i m_XMM0, m_XMM2, m_XMM3, m_XMM5, m_XMM6; + int16* vec1L = ( int16* )vec1A; + int16* vec2L = ( int16* )vec2A; + + int32 resultL = 0; + uint32 alignOffSetL = 0; + + m_XMM5 = _mm_xor_si128( m_XMM5, m_XMM5 ); + m_XMM6 = _mm_xor_si128( m_XMM6, m_XMM6 ); + + alignOffSetL = sizeA % 16; + sizeA >>= 4; + + if( sizeA ) + { + while( sizeA > 0 ) + { + m_XMM0 = _mm_load_si128( (__m128i *)&0[vec1L] ); + m_XMM5 = _mm_add_epi32( m_XMM5, m_XMM6 ); + + m_XMM2 = _mm_load_si128( (__m128i *)&0[vec2L] ); + + m_XMM6 = _mm_load_si128( (__m128i *)&8[vec1L] ); + + m_XMM0 = _mm_madd_epi16( m_XMM0, m_XMM2 ); + + m_XMM5 = _mm_add_epi32( m_XMM5, m_XMM0 ); + + m_XMM3 = _mm_load_si128( (__m128i *)&8[vec2L] ); + + m_XMM6 = _mm_madd_epi16( m_XMM6, m_XMM3 ); + + vec1L += 16; + vec2L += 16; + sizeA--; + } + + /* sum up accumulators */ + m_XMM5 = _mm_add_epi32( m_XMM5, m_XMM6 ); + + m_XMM0 = _mm_load_si128( (__m128i *)&m_XMM5 ); + + resultL = _mm_cvtsi128_si32( m_XMM0 ); /* 1st 32bits */ + + m_XMM0 = _mm_srli_si128( m_XMM0, 4 ); + + resultL += _mm_cvtsi128_si32( m_XMM0 ); /* 2nd 32bits */ + + m_XMM0 = _mm_srli_si128( m_XMM0, 4 ); + + resultL += _mm_cvtsi128_si32( m_XMM0 ); /* 3rd 32bits */ + + m_XMM0 = _mm_srli_si128( m_XMM0, 4 ); + + resultL += _mm_cvtsi128_si32( m_XMM0 ); /* 4th 32bits */ + } + + switch( alignOffSetL ) + { + case 15: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 14: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 13: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 12: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 11: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 10: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 9: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 8: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 7: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 6: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 5: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 4: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 3: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 2: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 1: + resultL += ( int32 )*vec1L++ * *vec2L++; + } + + return resultL; +} + +/* ------------------------------------------------------------------------- */ + + +/** Using full register (128-bit) in SSE2 to calculate dot product (non aligned version). + * Dependencies: memory does not need to be 16-bit aligned + * Return Value: int32 containing dot product + */ +int32 bbs_dotProduct_u128SSE2( const int16* vec1A, const int16* vec2A, uint32 sizeA ) +{ + __m128i m_XMM0, m_XMM2, m_XMM3, m_XMM5, m_XMM6; + int16* vec1L = ( int16* )vec1A; + int16* vec2L = ( int16* )vec2A; + int32 resultL = 0; + uint32 alignOffSetL = 0; + + /* initialize registers to 0 */ + m_XMM5 = _mm_xor_si128( m_XMM5, m_XMM5 ); + m_XMM6 = _mm_xor_si128( m_XMM6, m_XMM6 ); + + + alignOffSetL = sizeA % 16; + sizeA >>= 4; + + if( sizeA ) + { + while( sizeA > 0 ) + { + m_XMM0 = _mm_loadu_si128( (__m128i *)&0[vec1L] ); + m_XMM5 = _mm_add_epi32( m_XMM5, m_XMM6 ); + + m_XMM2 = _mm_loadu_si128( (__m128i *)&0[vec2L] ); + + m_XMM6 = _mm_loadu_si128( (__m128i *)&8[vec1L] ); + + m_XMM0 = _mm_madd_epi16( m_XMM0, m_XMM2 ); + + m_XMM5 = _mm_add_epi32( m_XMM5, m_XMM0 ); + + m_XMM3 = _mm_loadu_si128( (__m128i *)&8[vec2L] ); + + m_XMM6 = _mm_madd_epi16( m_XMM6, m_XMM3 ); + + vec1L += 16; + vec2L += 16; + sizeA--; + } + + /* sum up accumulators */ + m_XMM5 = _mm_add_epi32( m_XMM5, m_XMM6 ); + + m_XMM0 = _mm_loadu_si128( (__m128i *)&m_XMM5 ); + + resultL = _mm_cvtsi128_si32( m_XMM0 ); /* 1st 32bits */ + + m_XMM0 = _mm_srli_si128( m_XMM0, 4 ); + + resultL += _mm_cvtsi128_si32( m_XMM0 ); /* 2nd 32bits */ + + m_XMM0 = _mm_srli_si128( m_XMM0, 4 ); + + resultL += _mm_cvtsi128_si32( m_XMM0 ); /* 3rd 32bits */ + + m_XMM0 = _mm_srli_si128( m_XMM0, 4 ); + + resultL += _mm_cvtsi128_si32( m_XMM0 ); /* 4th 32bits */ + } + + + switch( alignOffSetL ) + { + case 15: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 14: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 13: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 12: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 11: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 10: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 9: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 8: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 7: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 6: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 5: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 4: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 3: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 2: + resultL += ( int32 )*vec1L++ * *vec2L++; + case 1: + resultL += ( int32 )*vec1L++ * *vec2L++; + } + + return resultL; +} + +/* ------------------------------------------------------------------------- */ + +#endif /* HW_SSE2 */ diff --git a/Embedded/common/src/b_BasicEm/MemSeg.c b/Embedded/common/src/b_BasicEm/MemSeg.c new file mode 100644 index 0000000..2fa509e --- /dev/null +++ b/Embedded/common/src/b_BasicEm/MemSeg.c @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/MemSeg.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Context.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_MemSeg_init( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA ) +{ + ptrA->memPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocIndexE = 0; + ptrA->sharedE = FALSE; + ptrA->idE = 0; + ptrA->dynMemManagerPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_MemSeg_exit( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA ) +{ + ptrA->memPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocIndexE = 0; + ptrA->sharedE = FALSE; + ptrA->idE = 0; + ptrA->dynMemManagerPtrE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_MemSeg_availableSize( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ) +{ + if( ptrA->dynMemManagerPtrE == NULL ) + { + return ( ptrA->sizeE == ptrA->allocIndexE ) ? 0 : ptrA->sizeE - ptrA->allocIndexE - 2 * ptrA->sharedE; + } + else + { + return 0xFFFFFFFF; + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_MemSeg_allocatedSize( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ) +{ + if( ptrA->dynMemManagerPtrE == NULL ) + { + return ptrA->allocIndexE; + } + else + { + return bbs_DynMemManager_allocatedSize( cpA, ptrA->dynMemManagerPtrE ); + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_MemSeg_usedSize( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ) +{ + if( ptrA->dynMemManagerPtrE == NULL ) + { + if( ptrA->sharedE ) + { + return ptrA->allocIndexE; + } + else + { + uint32 indexL = 0; + uint32 countL = 0; + while( indexL < ptrA->allocIndexE ) + { + uint32 sizeL = *( uint32* )( ptrA->memPtrE + indexL ); + indexL += ( sizeL & 0xFFFFFFFE ); + if( ( sizeL & 1 ) == 0 ) + { + countL += sizeL - 2; + } + } + return countL; + } + } + else + { + return bbs_MemSeg_allocatedSize( cpA, ptrA ); + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_MemSeg_blocks( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ) +{ + uint32 indexL = 0; + uint32 countL = 0; + + if( ptrA->sharedE ) return 0; + + while( indexL < ptrA->allocIndexE ) + { + uint32 sizeL = *( uint32* )( ptrA->memPtrE + indexL ); + indexL += ( sizeL & 0xFFFFFFFE ); + countL++; + } + return countL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_MemSeg_usedBlocks( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ) +{ + uint32 indexL = 0; + uint32 countL = 0; + + if( ptrA->sharedE ) return 0; + + while( indexL < ptrA->allocIndexE ) + { + uint32 sizeL = *( uint32* )( ptrA->memPtrE + indexL ); + indexL += ( sizeL & 0xFFFFFFFE ); + countL += ( ( sizeL & 1 ) == 0 ); + } + return countL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg bbs_MemSeg_create( struct bbs_Context* cpA, + void* memPtrA, uint32 sizeA ) +{ + struct bbs_MemSeg memSegL; + memSegL.memPtrE = ( uint16* )memPtrA; + memSegL.sizeE = sizeA & 0xFFFFFFFE; /* enforce even size to avoid overflow problems */ + memSegL.allocIndexE = 0; + memSegL.sharedE = FALSE; + memSegL.idE = 0; + memSegL.dynMemManagerPtrE = NULL; + return memSegL; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg bbs_MemSeg_createShared( struct bbs_Context* cpA, + void* memPtrA, uint32 sizeA ) +{ + struct bbs_MemSeg memSegL; + memSegL.memPtrE = ( uint16* )memPtrA; + memSegL.sizeE = sizeA; + memSegL.allocIndexE = 0; + memSegL.sharedE = TRUE; + memSegL.idE = 0; + memSegL.dynMemManagerPtrE = NULL; + return memSegL; +} + +/* ------------------------------------------------------------------------- */ + +void* bbs_MemSeg_alloc( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA, + uint32 sizeA ) +{ + uint16* memPtrL = NULL; + + if( bbs_Context_error( cpA ) ) return NULL; + + if( !ptrA->sharedE ) + { + if( ptrA->dynMemManagerPtrE == NULL ) + { + uint32 effSizeL = sizeA + ( sizeA & 1 ) + 2; /* effective block size */ + memPtrL = ptrA->memPtrE + ptrA->allocIndexE; + *( ( uint32* )memPtrL ) = effSizeL; + memPtrL += 2; + if( ptrA->allocIndexE + effSizeL > ptrA->sizeE ) + { + bbs_ERR2( bbs_ERR_MEMORY_OVERFLOW, + "uint16* bbs_MemSeg_alloc( struct bbs_MemSeg* ptrA, uint32 sizeA ):\n" + "Exclusive Memory overflow. Segment size: %i. Requested size: %i", ptrA->sizeE, sizeA ); + return NULL; + } + ptrA->allocIndexE += effSizeL; + } + else + { + memPtrL = bbs_DynMemManager_alloc( cpA, ptrA->dynMemManagerPtrE, ptrA, sizeA ); + } + } + else + { + uint32 effSizeL = sizeA + ( sizeA & 1 ); /* effective block size */ + + if( ptrA->allocIndexE + effSizeL > ptrA->sizeE + ( ptrA->sizeE & 1 ) ) + { + if( ptrA->dynMemManagerPtrE == NULL ) + { + bbs_ERR2( bbs_ERR_MEMORY_OVERFLOW, + "uint16* bbs_MemSeg_alloc( struct bbs_MemSeg* ptrA, uint32 sizeA ):\n" + "Shared Memory overflow. Segment size: %i. Requested size: %i", ptrA->sizeE, sizeA ); + return NULL; + } + else + { + uint32 actualBlockSizeL = 0; + ptrA->memPtrE = bbs_DynMemManager_nextBlock( cpA, ptrA->dynMemManagerPtrE, ptrA, ptrA->memPtrE, effSizeL, &actualBlockSizeL ); + ptrA->sizeE = actualBlockSizeL; + ptrA->allocIndexE = 0; + } + } + + memPtrL = ptrA->memPtrE + ptrA->allocIndexE; + ptrA->allocIndexE += effSizeL; + } + + #if defined( HW_TMS320C5x ) + #ifdef DEBUG2 + { + /* check if segment crosses page boundary */ + if( ( ( ( uint32 ) ptrA->memPtrE ) >> 16 ) != + ( ( ( uint32 ) ptrA->memPtrE + ( ptrA->sizeE - 1 ) ) >> 16 ) ) + { + bbs_ERROR0( "uint16* bbs_MemSeg_alloc( struct bbs_MemSeg* ptrA, uint32 sizeA ):\nSegment crosses page boundary\n" ); + return NULL; + } + } + #endif + #endif + + return memPtrL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_MemSeg_free( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA, + void* memPtrA ) +{ + bbs_DEF_fNameL( "void bbs_MemSeg_free( struct bbs_MemSeg* ptrA, void* memPtrA )" ) + + if( bbs_Context_error( cpA ) ) return; + + /** only valid exclusive segments can be freed */ + if( ptrA == NULL || memPtrA == NULL || ptrA->sharedE ) return; + + if( ptrA->dynMemManagerPtrE != NULL ) + { + bbs_DynMemManager_free( cpA, ptrA->dynMemManagerPtrE, memPtrA ); + } + else + { + uint32 indexL, sizeL; + uint16* memPtrL; + + if( ptrA == NULL || memPtrA == NULL ) return; + if( ptrA->sharedE ) return; + + #ifdef HW_TMS320C5x + indexL = ( uint32 ) memPtrA - ( uint32 ) ptrA->memPtrE - 2; + #else + indexL = ( uint16* )memPtrA - ptrA->memPtrE - 2; + #endif + + memPtrL = ptrA->memPtrE + indexL; + sizeL = *( ( int32* )memPtrL ); + + /* checks */ + if( indexL > ptrA->allocIndexE || ( indexL & 1 ) != 0 ) + { + bbs_ERROR4( "%s\n: Invalid memory.\n" + "sizeE = %i\n" + "allocIndexE = %i\n" + "indexL = %i\n", + fNameL, + ptrA->sizeE, + ptrA->allocIndexE, + indexL ); + return; + } + + if( ( sizeL & 1 ) != 0 ) + { + bbs_ERROR1( "%s\n: Memory block was already freed once", fNameL ); + return; + } + + *( ( uint32* )memPtrL ) += 1; /* odd size value indicates unused memory block */ + + /* free last unused blocks if any */ + if( indexL + sizeL == ptrA->allocIndexE ) + { + uint32 newAllocIndexL = 0; + indexL = 0; + while( indexL < ptrA->allocIndexE ) + { + uint32 sizeL = *( uint32* )( ptrA->memPtrE + indexL ); + indexL += ( sizeL & 0xFFFFFFFE ); + if( ( sizeL & 1 ) == 0 ) + { + newAllocIndexL = indexL; + } + } + + ptrA->allocIndexE = newAllocIndexL; + } + + #ifdef DEBUG2 + bbs_MemSeg_checkConsistency( cpA, ptrA ); + #endif + + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_MemSeg_checkConsistency( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ) +{ + uint32 indexL = 0; + + if( ptrA->sharedE ) return; + + while( indexL < ptrA->allocIndexE ) + { + uint32 sizeL = *( uint32* )( ptrA->memPtrE + indexL ); + indexL += ( sizeL & 0xFFFFFFFE ); + } + + if( indexL != ptrA->allocIndexE ) + { + bbs_ERROR0( "Memory consistency check failed" ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_BasicEm/MemSeg.h b/Embedded/common/src/b_BasicEm/MemSeg.h new file mode 100644 index 0000000..cf309c9 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/MemSeg.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_MEM_SEG_EM_H +#define bbs_MEM_SEG_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/DynMemManager.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_Context; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* overhead memory needed for each memory block allocated (exclusive memory only) */ +#define bbs_MEM_BLOCK_OVERHD 2 + +/* Segment IDs */ +#define bbs_SEG_DEFAULT 0 + +#if defined( HW_TMS320C5x ) || defined( HW_MeP ) || defined( bbs_MEP_MEM_CONFIG ) + #define bbs_SEG_DA 1 + #define bbs_SEG_DA_ALT 2 + #define bbs_SEG_SA 3 + #define bbs_SEG_SA_ALT 4 + #define bbs_SEG_EXT 5 + #define bbs_SEG_EXT_ALT 6 +#elif defined ( bbs_KD_MEM_CONFIG ) || defined ( HW_KD_EASYSHARE ) +/* on-chip optimization for Kodak Easyshare project */ + #define bbs_SEG_DA 1 /* = internal RAM segment */ + #define bbs_SEG_DA_ALT 0 + #define bbs_SEG_SA 0 + #define bbs_SEG_SA_ALT 0 + #define bbs_SEG_EXT 0 + #define bbs_SEG_EXT_ALT 0 +#endif + +/* ---- object definition -------------------------------------------------- */ + +/** Descriptor of a coherent memory segment available for memory management. + * How management works + * - Memory is arranged in blocks + * - Each block refers to a single call of function alloc() + * - Each block is aligned at 32bit + * - The size of each block is even (32bit aligned size) + * Uique (non-shared) segments: + * - Each block has a preceding 32 bit value indication its length + * - Function free() marks the corresponding block 'unused' and + * removes subsequently any unused block at the last position of allocated memory + * Shared segments: + * - No write access to memory block by function alloc() + * - Function free has no effect + * Identifier: + * - Each segment contains an ID. The segment with the ID 0 is the default segment. + */ +struct bbs_MemSeg +{ + /* all member variables are considered read only. Only change them through functions */ + + /** pointer to memory */ + uint16* memPtrE; + + /** size of memory segment in 16 bit units */ + uint32 sizeE; + + /** current allocation index in 16 bit units (index is always even -> 32 bit alignment enforced) */ + uint32 allocIndexE; + + /** Indicates that this isegment is to be shared among multiple objects */ + flag sharedE; + + /** ID of segment, id=0: unspecified */ + uint32 idE; + + /** pointer to external memory manager */ + struct bbs_DynMemManager* dynMemManagerPtrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_MemSeg */ +void bbs_MemSeg_init( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA ); + +/** resets bbs_MemSeg */ +void bbs_MemSeg_exit( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns available 16bit units of memeory in given segment; (allocation is always 32 bit aligned) */ +uint32 bbs_MemSeg_availableSize( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ); + +/** returns currently allocated size in 16bit units of memeory in given segment */ +uint32 bbs_MemSeg_allocatedSize( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ); + +/** returns effectively used memory amount allocated size - unused blocks - overhead */ +uint32 bbs_MemSeg_usedSize( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ); + +/** counts amount of memory blocks allocated */ +uint32 bbs_MemSeg_blocks( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ); + +/** counts amount of memory blocks currently used */ +uint32 bbs_MemSeg_usedBlocks( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creation of a exclusive memory segment; memPtrA must be 32-bit aligned */ +struct bbs_MemSeg bbs_MemSeg_create( struct bbs_Context* cpA, + void* memPtrA, + uint32 sizeA ); + +/** creation of a shared memory segment; memPtrA must be 32-bit aligned */ +struct bbs_MemSeg bbs_MemSeg_createShared( struct bbs_Context* cpA, + void* memPtrA, + uint32 sizeA ); + +/** allocation of memory (very fast); sizeA specifies number of 16bit units; (allocation is always 32 bit aligned) */ +void* bbs_MemSeg_alloc( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA, + uint32 sizeA ); + +/** Frees allocated memory + * If segment is shared, ptrA == NULL or memPtrA == NULL, nothing happens + */ +void bbs_MemSeg_free( struct bbs_Context* cpA, + struct bbs_MemSeg* ptrA, + void* memPtrA ); + +/** checks consistency of memory */ +void bbs_MemSeg_checkConsistency( struct bbs_Context* cpA, + const struct bbs_MemSeg* ptrA ); + +#endif /* bbs_MEM_SEG_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/MemTbl.c b/Embedded/common/src/b_BasicEm/MemTbl.c new file mode 100644 index 0000000..2555bd1 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/MemTbl.c @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +flag bbs_MemTbl_memOverlap( const uint16* memPtr1A, uint32 size1A, + const uint16* memPtr2A, uint32 size2A ) +{ + int32 diffL = memPtr2A - memPtr1A; + if( diffL >= 0 && diffL < ( int32 )size1A ) return TRUE; + diffL += ( int32 )size2A; + if( diffL >= 0 && diffL < ( int32 )size1A ) return TRUE; + return FALSE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_MemTbl_init( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ) +{ + uint32 iL; + for( iL = 0; iL < bbs_MAX_MEM_SEGS; iL++ ) + { + bbs_MemSeg_init( cpA, &ptrA->esArrE[ iL ] ); + bbs_MemSeg_init( cpA, &ptrA->ssArrE[ iL ] ); + ptrA->espArrE[ iL ] = NULL; + } + ptrA->esSizeE = 0; + ptrA->ssSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_MemTbl_exit( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ) +{ + uint32 iL; + for( iL = 0; iL < bbs_MAX_MEM_SEGS; iL++ ) + { + bbs_MemSeg_exit( cpA, &ptrA->esArrE[ iL ] ); + bbs_MemSeg_exit( cpA, &ptrA->ssArrE[ iL ] ); + ptrA->espArrE[ iL ] = NULL; + } + ptrA->esSizeE = 0; + ptrA->ssSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +flag bbs_MemTbl_overlap( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + const void* memPtrA, uint32 sizeA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->esSizeE; iL++ ) + { + if( bbs_MemTbl_memOverlap( ptrA->espArrE[ iL ]->memPtrE, + ptrA->espArrE[ iL ]->sizeE, + memPtrA, sizeA ) ) + { + return TRUE; + } + } + + for( iL = 0; iL < ptrA->ssSizeE; iL++ ) + { + if( bbs_MemTbl_memOverlap( ptrA->ssArrE[ iL ].memPtrE, + ptrA->ssArrE[ iL ].sizeE, + memPtrA, sizeA ) ) + { + return TRUE; + } + } + + return FALSE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_MemTbl_create( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + void* memPtrA, + uint32 sizeA, + uint32 sharedSubSizeA ) +{ + if( sharedSubSizeA > sizeA ) + { + bbs_ERROR0( "struct bbs_MemTbl bbs_MemTbl_create( void* memPtrA, uint32 sizeA, uint32 sharedSubSizeA ):\n" + "sharedSubSizeA > sizeA" ); + return; + } + bbs_MemTbl_init( cpA, ptrA ); + + + ptrA->esArrE[ 0 ] = bbs_MemSeg_create( cpA, memPtrA, sizeA - sharedSubSizeA ); + #ifdef HW_TMS320C5x + ptrA->ssArrE[ 0 ] = bbs_MemSeg_createShared( cpA, ( uint16* ) ( ( int32 ) ( ( uint16* )memPtrA ) + sizeA - sharedSubSizeA ), sharedSubSizeA ); + #else + ptrA->ssArrE[ 0 ] = bbs_MemSeg_createShared( cpA, ( uint16* )memPtrA + sizeA - sharedSubSizeA, sharedSubSizeA ); + #endif + ptrA->espArrE[ 0 ] = &ptrA->esArrE[ 0 ]; + + ptrA->esSizeE = 1; + ptrA->ssSizeE = 1; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_MemTbl_add( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + void* memPtrA, + uint32 sizeA, + uint32 idA ) +{ + if( ptrA->esSizeE == bbs_MAX_MEM_SEGS ) + { + bbs_ERROR0( "void bbs_MemTbl_add( struct bbs_MemTbl* ptrA, void* memPtrA, uint32 sizeA ):\n" + "Table is full! Increase constant bbs_MAX_MEM_SEGS" ); + return; + } + ptrA->esArrE[ ptrA->esSizeE ] = bbs_MemSeg_create( cpA, memPtrA, sizeA ); + ptrA->esArrE[ ptrA->esSizeE ].idE = idA; + ptrA->espArrE[ ptrA->esSizeE ] = &ptrA->esArrE[ ptrA->esSizeE ]; + ptrA->esSizeE++; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_MemTbl_addShared( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + void* memPtrA, + uint32 sizeA, + uint32 idA ) +{ + if( ptrA->ssSizeE == bbs_MAX_MEM_SEGS ) + { + bbs_ERROR0( "void bbs_MemTbl_addShared( struct bbs_MemTbl* ptrA, void* memPtrA, uint32 sizeA ):\n" + "Table is full! Increase constant bbs_MAX_MEM_SEGS" ); + return; + } + ptrA->ssArrE[ ptrA->ssSizeE ] = bbs_MemSeg_createShared( cpA, memPtrA, sizeA ); + ptrA->ssArrE[ ptrA->ssSizeE ].idE = idA; + ptrA->ssSizeE++; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg* bbs_MemTbl_segPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 idA ) +{ + uint32 iL; + if( ptrA->esSizeE == 0 ) + { + bbs_ERROR0( "bbs_MemTbl_segPtr(): Table contains no exclusive segments." ); + return NULL; + } + if( idA > 0 ) + { + for( iL = 0; iL < ptrA->esSizeE; iL++ ) + { + if( idA == ptrA->espArrE[ iL ]->idE ) return ptrA->espArrE[ iL ]; + } + } + for( iL = 0; iL < ptrA->esSizeE; iL++ ) + { + if( ptrA->espArrE[ iL ]->sizeE > 0 || + ptrA->espArrE[ iL ]->dynMemManagerPtrE != 0 ) + { + return ptrA->espArrE[ iL ]; + } + } + bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW, + "bbs_MemTbl_segPtr(): Table contains no valid exclusive segments." ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg* bbs_MemTbl_sharedSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 idA ) +{ + uint32 iL; + if( ptrA->ssSizeE == 0 ) + { + bbs_ERROR0( "bbs_MemTbl_sharedSegPtr(): Table contains no shared segments." ); + return NULL; + } + if( idA > 0 ) + { + for( iL = 0; iL < ptrA->ssSizeE; iL++ ) + { + if( idA == ptrA->ssArrE[ iL ].idE ) return &ptrA->ssArrE[ iL ]; + } + } + for( iL = 0; iL < ptrA->ssSizeE; iL++ ) + { + if( ptrA->ssArrE[ iL ].sizeE > 0 || + ptrA->ssArrE[ iL ].dynMemManagerPtrE != 0 ) + { + return &ptrA->ssArrE[ iL ]; + } + } + bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW, + "bbs_MemTbl_sharedSegPtr(): Table contains no valid shared segments." ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 minSizeA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->esSizeE; iL++ ) + { + if( bbs_MemSeg_availableSize( cpA, ptrA->espArrE[ iL ] ) >= minSizeA ) break; + } + if( iL == ptrA->esSizeE ) + { + if( ptrA->esSizeE == 0 ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n" + "Table contains no exclusive segments" ); + return NULL; + } + else + { + bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW, + "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n" + "Could not find segment with sufficient free space" ); + return NULL; + } + } + if( ptrA->espArrE[ iL ]->sharedE ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n" + "Table corrupt: Found shared segment in exclusive table" ); + return NULL; + } + + return ptrA->espArrE[ iL ]; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ) +{ + uint32 iL; + uint32 maxIndexL = 0; + uint32 maxSizeL = 0; + + if( ptrA->esSizeE == 0 ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_MemTbl* ptrA ):\n" + "No exclusive segments available" ); + return NULL; + } + + for( iL = 0; iL < ptrA->esSizeE; iL++ ) + { + uint32 sizeL = bbs_MemSeg_availableSize( cpA, ptrA->espArrE[ iL ] ); + if( sizeL > maxSizeL ) + { + maxSizeL = sizeL; + maxIndexL = iL; + } + } + + if( ptrA->espArrE[ maxIndexL ]->sharedE ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_MemTbl* ptrA ):\n" + "Table corrupt: Found shared segment in exclusive table" ); + return NULL; + } + + return ptrA->espArrE[ maxIndexL ]; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 minSizeA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->ssSizeE; iL++ ) + { + if( bbs_MemSeg_availableSize( cpA, &ptrA->ssArrE[ iL ] ) >= minSizeA ) break; + } + if( iL == ptrA->ssSizeE ) + { + if( ptrA->esSizeE == 0 ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n" + "Table contains no shared segments" ); + return NULL; + } + else + { + bbs_ERR0( bbs_ERR_MEMORY_OVERFLOW, + "struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n" + "Could not find segment with sufficient free space" ); + return NULL; + } + } + if( !ptrA->ssArrE[ iL ].sharedE ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_MemTbl* ptrA, uint32 minSizeA ):\n" + "Table corrupt: Found exclusive segment in shared table" ); + return NULL; + } + + return &ptrA->ssArrE[ iL ]; +} + +/* ------------------------------------------------------------------------- */ + +struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ) +{ + uint32 iL; + uint32 maxIndexL = 0; + uint32 maxSizeL = 0; + + if( ptrA->ssSizeE == 0 ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_MemTbl* ptrA ):\n" + "No shared segments available" ); + return NULL; + } + + for( iL = 0; iL < ptrA->ssSizeE; iL++ ) + { + uint32 sizeL = bbs_MemSeg_availableSize( cpA, &ptrA->ssArrE[ iL ] ); + if( sizeL > maxSizeL ) + { + maxSizeL = sizeL; + maxIndexL = iL; + } + } + + if( !ptrA->ssArrE[ maxIndexL ].sharedE ) + { + bbs_ERROR0( "struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_MemTbl* ptrA ):\n" + "Table corrupt: Found exclusive segment in shared table" ); + return NULL; + } + + return &ptrA->ssArrE[ maxIndexL ]; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/MemTbl.h b/Embedded/common/src/b_BasicEm/MemTbl.h new file mode 100644 index 0000000..9364af3 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/MemTbl.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_MEM_TBL_EM_H +#define bbs_MEM_TBL_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bbs_Context; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* maximum number of exclusive and shared memory segments used, increase this number if needed */ +#define bbs_MAX_MEM_SEGS 4 + +/* ---- object definition -------------------------------------------------- */ + +/** Descriptor of a set of memory segments + * The first segment in each array (exclusive and shared) with a size > 0 is + * the default segment. + */ +struct bbs_MemTbl +{ + /* number of exclusive memory segments */ + uint32 esSizeE; + + /** array of exclusive memory segments (for initialisation purposes only ) */ + struct bbs_MemSeg esArrE[ bbs_MAX_MEM_SEGS ]; + + /** array of pointer to exclusive memory segments */ + struct bbs_MemSeg* espArrE[ bbs_MAX_MEM_SEGS ]; + + /* number of shared memory segments */ + uint32 ssSizeE; + + /** array of shared memory segments */ + struct bbs_MemSeg ssArrE[ bbs_MAX_MEM_SEGS ]; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_MemTbl */ +void bbs_MemTbl_init( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ); + +/** resets bbs_MemTbl */ +void bbs_MemTbl_exit( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* indicates whether memory segment overalps with any segment in memory table */ +flag bbs_MemTbl_overlap( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + const void* memPtrA, uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creates a memory table with one exclusive and one shared segment from a coherent memory block */ +void bbs_MemTbl_create( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + void* memPtrA, + uint32 sizeA, + uint32 sharedSubSizeA ); + +/** adds new exclusive segment to table ( default segment must be added first ) */ +void bbs_MemTbl_add( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + void* memPtrA, + uint32 sizeA, + uint32 idA ); + +/** adds new shared segment to table ( default segment must be added first ) */ +void bbs_MemTbl_addShared( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + void* memPtrA, + uint32 sizeA, + uint32 idA ); + +/** returns specified segment. If specified segment is not found the default segment is returned */ +struct bbs_MemSeg* bbs_MemTbl_segPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 idA ); + +struct bbs_MemSeg* bbs_MemTbl_sharedSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 idA ); + +/* Search functions below are obsolete. Please use bbs_MemTbl_segPtr or bbs_MemTbl_sharedSegPtr instead. */ + +/** returns pointer to fastest exclusive segment that has at least minSizeA words available */ +struct bbs_MemSeg* bbs_MemTbl_fastestSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 minSizeA ); + +/** returns pointer to exclusive segment that has most words available */ +struct bbs_MemSeg* bbs_MemTbl_largestSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ); + +/** returns fastest shared segment that has at least minSizeA words available */ +struct bbs_MemSeg* bbs_MemTbl_fastestSharedSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA, + uint32 minSizeA ); + +/** returns shared segment that has most words available */ +struct bbs_MemSeg* bbs_MemTbl_largestSharedSegPtr( struct bbs_Context* cpA, + struct bbs_MemTbl* ptrA ); + +#endif /* bbs_MEM_TBL_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Memory.c b/Embedded/common/src/b_BasicEm/Memory.c new file mode 100644 index 0000000..d3b965d --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Memory.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" +/* +#include <string.h> +*/ +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* +void* bbs_memcpy( void* dstA, const void* srcA, uint32 sizeA ) +{ + if( sizeA & 1 ) + { + bbs_ERROR0( "bbs_memcpy( .... ): sizeA must be even" ); + return NULL; + } + return bbs_memcpy16( dstA, srcA, sizeA >> 1 ); +} +*/ +/* ------------------------------------------------------------------------- */ + +void* bbs_memcpy16( void* dstA, const void* srcA, uint32 sizeA ) +{ +#ifdef HW_TMS320C5x + if( ( ( int32 ) dstA >> 16 ) == ( ( ( int32 ) dstA + sizeA ) >> 16 ) && + ( ( int32 ) srcA >> 16 ) == ( ( ( int32 ) srcA + sizeA ) >> 16 ) ) + { + /* fast version, works only if pointers do not cross page boundary. */ + uint16* dstL = ( uint16* )dstA; + const uint16* srcL = ( uint16* )srcA; + uint16 iL; + for( iL = sizeA; iL--; ) + { + *dstL++ = *srcL++; + } + } + else + { + /* safe version */ + uint32 iL; + for( iL = 0; iL < sizeA; iL++ ) + { + *( uint16* ) ( ( int32 ) dstA + iL ) = *( uint16* ) ( ( int32 ) srcA + iL ); + } + } + return dstA; +#else + uint16* dstL = ( uint16* )dstA; + const uint16* srcL = ( uint16* )srcA; + + for( ; sizeA >= 4; sizeA -= 4 ) + { + dstL[ 0 ] = srcL[ 0 ]; + dstL[ 1 ] = srcL[ 1 ]; + dstL[ 2 ] = srcL[ 2 ]; + dstL[ 3 ] = srcL[ 3 ]; + dstL += 4; + srcL += 4; + } + + for( ; sizeA > 0; sizeA-- ) + { + *dstL++ = *srcL++; + } + + return dstA; +#endif +} + +/* ------------------------------------------------------------------------- */ + +void* bbs_memcpy32( void* dstA, const void* srcA, uint32 sizeA ) +{ +#ifdef HW_TMS320C5x + if( ( ( int32 ) dstA >> 16 ) == ( ( ( int32 ) dstA + ( sizeA << 1 ) ) >> 16 ) && + ( ( int32 ) srcA >> 16 ) == ( ( ( int32 ) srcA + ( sizeA << 1 ) ) >> 16 ) ) + { + /* fast version, works only if pointers do not cross page boundary. */ + uint32* dstL = ( uint32* )dstA; + const uint32* srcL = ( uint32* )srcA; + uint16 iL; + for( iL = sizeA; iL--; ) + { + *dstL++ = *srcL++; + } + } + else + { + /* safe version */ + uint32 iL; + sizeA <<= 1; + for( iL = 0; iL < sizeA; iL += 2 ) + { + *( uint32* ) ( ( int32 ) dstA + iL ) = *( uint32* ) ( ( int32 ) srcA + iL ); + } + } + return dstA; +/* + uint16* dstL = ( uint16* )dstA; + const uint16* srcL = ( uint16* )srcA; + + // copying with base object-size of 16bit + // is more efficient on 16 bit architecture + sizeA <<= 1; + + for( ; sizeA >= 4; sizeA -= 4 ) + { + dstL[ 0 ] = srcL[ 0 ]; + dstL[ 1 ] = srcL[ 1 ]; + dstL[ 2 ] = srcL[ 2 ]; + dstL[ 3 ] = srcL[ 3 ]; + dstL += 4; + srcL += 4; + } + + for( ; sizeA > 0; sizeA-- ) + { + *dstL++ = *srcL++; + } + + return dstA; +*/ +#else /* 32bit architectures */ + + uint32* dstL = ( uint32* )dstA; + const uint32* srcL = ( uint32* )srcA; + + for( ; sizeA >= 4; sizeA -= 4 ) + { + dstL[ 0 ] = srcL[ 0 ]; + dstL[ 1 ] = srcL[ 1 ]; + dstL[ 2 ] = srcL[ 2 ]; + dstL[ 3 ] = srcL[ 3 ]; + dstL += 4; + srcL += 4; + } + + for( ; sizeA > 0; sizeA-- ) + { + *dstL++ = *srcL++; + } + + return dstA; + +#endif +} + +/* ------------------------------------------------------------------------- */ + +void* bbs_memset16( void* dstA, uint16 valA, uint32 sizeA ) +{ + uint32 iL; + uint16* dstL = ( uint16* )dstA; + /* to be optimized */ + for( iL = 0; iL < sizeA; iL++ ) + { + *dstL++ = valA; + } + return dstA; +} + +/* ------------------------------------------------------------------------- */ + +void* bbs_memset32( void* dstA, uint32 valA, uint32 sizeA ) +{ + uint32 iL; + uint32* dstL = ( uint32* )dstA; + /* to be optimized */ + for( iL = 0; iL < sizeA; iL++ ) + { + *dstL++ = valA; + } + return dstA; +} + +/* ------------------------------------------------------------------------- */ + diff --git a/Embedded/common/src/b_BasicEm/Memory.h b/Embedded/common/src/b_BasicEm/Memory.h new file mode 100644 index 0000000..b533a25 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Memory.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_MEMORY_EM_H +#define bbs_MEMORY_EM_H + +/** + * This files contains memory related functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** copies memory for src to dst (no overlap allowed); returns dstA + * src & dst data must be 16 bit aligned + */ +/* void* bbs_memcpy( void* dstA, const void* srcA, uint32 sizeA ); */ + +/** copies memory for src to dst (no overlap allowed), size is given in 16-bit words + * src & dst data must be 16 bit aligned + * returns dstA + */ +void* bbs_memcpy16( void* dstA, const void* srcA, uint32 sizeA ); + +/** copies memory for src to dst (no overlap allowed), size is given in 32-bit words + * src & dst data must be 32 bit aligned + * returns dstA + */ +void* bbs_memcpy32( void* dstA, const void* srcA, uint32 sizeA ); + +/** fills memory with a value, size is given in 16-bit words + * dst data must be 16 bit aligned + * returns dstA + */ +void* bbs_memset16( void* dstA, uint16 valA, uint32 sizeA ); + +/** fills memory with a value, size is given in 32-bit words + * dst data must be 32 bit aligned + * returns dstA + */ +void* bbs_memset32( void* dstA, uint32 valA, uint32 sizeA ); + +#endif /* bbs_MEMORY_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/Phase.c b/Embedded/common/src/b_BasicEm/Phase.c new file mode 100644 index 0000000..6fdbd35 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Phase.c @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Phase.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +#ifndef bbs_SIN_INTERPOLATION_METHOD_2 +const int32 bbs_sin32_table1G[] = +{ + 0, 1608, 411648, 1607, 823040, 1606, 1234176, 1602, + 1644288, 1599, 2053632, 1594, 2461696, 1588, 2868224, 1581, + 3272960, 1574, 3675904, 1564, 4076288, 1556, 4474624, 1545, + 4870144, 1533, 5262592, 1521, 5651968, 1508, 6038016, 1493, + 6420224, 1478, 6798592, 1463, 7173120, 1445, 7543040, 1428, + 7908608, 1409, 8269312, 1390, 8625152, 1369, 8975616, 1348, + 9320704, 1327, 9660416, 1303, 9993984, 1280, 10321664, 1256, + 10643200, 1231, 10958336, 1205, 11266816, 1178, 11568384, 1151, + 11863040, 1124, 12150784, 1094, 12430848, 1066, 12703744, 1036, + 12968960, 1005, 13226240, 974, 13475584, 942, 13716736, 910, + 13949696, 877, 14174208, 844, 14390272, 810, 14597632, 775, + 14796032, 741, 14985728, 705, 15166208, 670, 15337728, 634, + 15500032, 597, 15652864, 561, 15796480, 523, 15930368, 486, + 16054784, 448, 16169472, 409, 16274176, 372, 16369408, 333, + 16454656, 295, 16530176, 255, 16595456, 217, 16651008, 177, + 16696320, 138, 16731648, 99, 16756992, 59, 16772096, 20, + 16777216, -20, 16772096, -59, 16756992, -99, 16731648, -138, + 16696320, -177, 16651008, -217, 16595456, -255, 16530176, -295, + 16454656, -333, 16369408, -372, 16274176, -409, 16169472, -448, + 16054784, -486, 15930368, -523, 15796480, -561, 15652864, -597, + 15500032, -634, 15337728, -670, 15166208, -705, 14985728, -741, + 14796032, -775, 14597632, -810, 14390272, -844, 14174208, -877, + 13949696, -910, 13716736, -942, 13475584, -974, 13226240, -1005, + 12968960, -1036, 12703744, -1066, 12430848, -1094, 12150784, -1124, + 11863040, -1151, 11568384, -1178, 11266816, -1205, 10958336, -1231, + 10643200, -1256, 10321664, -1280, 9993984, -1303, 9660416, -1327, + 9320704, -1348, 8975616, -1369, 8625152, -1390, 8269312, -1409, + 7908608, -1428, 7543040, -1445, 7173120, -1463, 6798592, -1478, + 6420224, -1493, 6038016, -1508, 5651968, -1521, 5262592, -1533, + 4870144, -1545, 4474624, -1556, 4076288, -1564, 3675904, -1574, + 3272960, -1581, 2868224, -1588, 2461696, -1594, 2053632, -1599, + 1644288, -1602, 1234176, -1606, 823040, -1607, 411648, -1608 +}; +#else +const int32 bbs_sin32_table2G[] = +{ + 0, 12907, -122, + 209469440, 12662, -368, + 410894336, 11926, -596, + 596525056, 10733, -802, + 759234560, 9129, -978, + 892780544, 7168, -1112, + 992002048, 4939, -1210, + 1053097984, 2516, -1256, + 1073741824, -4, -1256, + 1053097984, -2519, -1210, + 992002048, -4944, -1112, + 892780544, -7173, -978, + 759234560, -9129, -802, + 596525056, -10734, -596, + 410894336, -11926, -368, + 209469440, -12663, -122 +}; +#endif + +int32 bbs_sin32( phase16 phaseA ) +{ +#ifndef bbs_SIN_INTERPOLATION_METHOD_2 + + int32 oL = ( phaseA & 0x00FF ); + uint16 indexL = ( ( phaseA & 0x7F00 ) >> 8 ) << 1; + int32 sinL = bbs_sin32_table1G[ indexL ] + oL * bbs_sin32_table1G[ indexL + 1 ]; + + if( ( phaseA & 0x8000 ) != 0 ) + { + return -sinL; + } + else + { + return sinL; + } + +#else /*bbs_SIN_INTERPOLATION_METHOD_2*/ + + int32 o1L = ( phaseA & 0x07FF ); + int32 o2L = ( o1L * o1L ) >> 8; + uint16 indexL = ( ( phaseA & 0x7800 ) >> 11 ) * 3; + int32 sinL = bbs_sin32_table2G[ indexL ] + ( ( o1L * bbs_sin32_table2G[ indexL + 1 ] ) << 3 ) + o2L * bbs_sin32_table2G[ indexL + 2 ]; + + if( ( phaseA & 0x8000 ) != 0 ) + { + return -sinL >> 6; + } + else + { + return sinL >> 6; + } + +#endif /*bbs_SIN_INTERPOLATION_METHOD_2*/ +} + +/** computation of sine tables (do not uncomment or remove) +void sin1Table() +{ + long iL; + for( iL = 0; iL < 128; iL++ ) + { + int32 phase1L = iL * 256; + int32 phase2L = phase1L + 256; + double angle1L = ( M_PI * phase1L ) / 32768; + double angle2L = ( M_PI * phase2L ) / 32768; + int32 sin1L = ( sin( angle1L ) * 65536 ); + int32 sin2L = ( sin( angle2L ) * 65536 ); + int32 diffL = sin2L - sin1L; + eout << iL << ": " << ( sin1L << 8 ) << " + oL * " << diffL << endl; + } +} + +void sin2Table() +{ + long iL; + for( iL = 0; iL < 16; iL++ ) + { + int32 p0L = iL * ( 1 << 11 ); + int32 p1L = p0L + ( 1 << 10 ); + int32 p2L = p0L + ( 1 << 11 ); + + double a0L = ( M_PI * p0L ) / ( 1 << 15 ); + double a1L = ( M_PI * p1L ) / ( 1 << 15 ); + double a2L = ( M_PI * p2L ) / ( 1 << 15 ); + + int32 s0L = ( sin( a0L ) * ( 1 << 16 ) ); + int32 s1L = ( sin( a1L ) * ( 1 << 16 ) ); + int32 s2L = ( sin( a2L ) * ( 1 << 16 ) ); + + int32 aL = 4 * s1L - 3 * s0L - s2L; + int32 bL = 2 * s2L + 2 * s0L - 4 * s1L; + + eout << iL << ": " << ( s0L << 14 ) << " + ( ( o1L * " << aL << " ) << 3 )" + << " + o2L * " << bL << endl; + } +} +*/ + +/* ------------------------------------------------------------------------- */ + +int32 bbs_cos32( phase16 phaseA ) +{ + return bbs_sin32( ( phase16 )( phaseA + bbs_M_PI_2_16 ) ); +} + +/* ------------------------------------------------------------------------- */ + +int16 bbs_sin16( phase16 phaseA ) +{ + return bbs_sin32( phaseA ) >> 10; +} + +/* ------------------------------------------------------------------------- */ + +int16 bbs_cos16( phase16 phaseA ) +{ + return bbs_sin32( ( phase16 )( phaseA + bbs_M_PI_2_16 ) ) >> 10; +} + +/* ------------------------------------------------------------------------- */ + +const int32 bbs_atan16_tableG[] = +{ + 0, 325, 332800, 326, 666624, 326, 1000448, 325, + 1333248, 324, 1665024, 323, 1995776, 323, 2326528, 322, + 2656256, 320, 2983936, 319, 3310592, 317, 3635200, 316, + 3958784, 314, 4280320, 312, 4599808, 310, 4917248, 308, + 5232640, 306, 5545984, 303, 5856256, 301, 6164480, 298, + 6469632, 296, 6772736, 292, 7071744, 291, 7369728, 287, + 7663616, 284, 7954432, 281, 8242176, 279, 8527872, 275, + 8809472, 272, 9088000, 269, 9363456, 265, 9634816, 263, + 9904128, 259, 10169344, 256, 10431488, 252, 10689536, 249, + 10944512, 246, 11196416, 243, 11445248, 239, 11689984, 236, + 11931648, 233, 12170240, 230, 12405760, 226, 12637184, 223, + 12865536, 219, 13089792, 217, 13312000, 213, 13530112, 210, + 13745152, 207, 13957120, 204, 14166016, 201, 14371840, 198, + 14574592, 195, 14774272, 192, 14970880, 189, 15164416, 186, + 15354880, 183, 15542272, 180, 15726592, 178, 15908864, 175, + 16088064, 172, 16264192, 169, 16437248, 167, 16608256, 165 +}; + +phase16 bbs_atan16( uint32 valA ) +{ + uint32 oL = valA & 0x03FF; + uint16 indexL = ( valA >> 10 ) << 1; + uint32 phaseL = bbs_atan16_tableG[ indexL ] + oL * bbs_atan16_tableG[ indexL + 1 ]; + return ( phase16 )( phaseL >> 11 ); +} + +/* ------------------------------------------------------------------------- */ + +phase16 bbs_phase16( int32 xA, int32 yA ) +{ + uint32 xL = ( xA > 0 ) ? xA : -xA; + uint32 yL = ( yA > 0 ) ? yA : -yA; + phase16 phaseL; + + if( xL == 0 && yL == 0 ) return 0; + + if( xL == yL ) + { + phaseL = bbs_M_PI_4_16; /*PI/4*/ + } + else if( xL > yL ) + { + if( yL >= 65536 ) /* avoid overflow (1 << 16) */ + { + uint32 shiftL = bbs_intLog2( yL ) - 15; + xL >>= shiftL; + yL >>= shiftL; + } + phaseL = bbs_atan16( ( yL << 16 ) / xL ); + } + else + { + if( xL >= 65536 ) /* avoid overflow (1 << 16) */ + { + uint32 shiftL = bbs_intLog2( xL ) - 15; + xL >>= shiftL; + yL >>= shiftL; + } + phaseL = bbs_M_PI_2_16 - bbs_atan16( ( xL << 16 ) / yL ); + } + + if( xA >= 0 ) + { + if( yA >= 0 ) + { + return phaseL; + } + else + { + return -phaseL; + } + } + else + { + if( yA >= 0 ) + { + return bbs_M_PI_16 - phaseL; + } + else + { + return phaseL - bbs_M_PI_16; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/Phase.h b/Embedded/common/src/b_BasicEm/Phase.h new file mode 100644 index 0000000..901f260 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/Phase.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_PHASE_EM_H +#define bbs_PHASE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +/** + * Phase data type. + * This data type represents a phase or angle value and takes advantage + * of the circular value range when doing arithmetig with an integer + * by ignoring overflow. + * The phase value range lies within [ - PI, PI [; + * The corresponding integer value range is [ MININT, MAXINT + 1 [. + * The phase data type is to be used whereever an angle is needed. + */ + +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** 8 bit phase value */ +typedef int8 phase8; + +/** 16 bit phase value */ +typedef int16 phase16; + +/** 32 bit phase value */ +typedef int32 phase32; + +/* ---- constants ---------------------------------------------------------- */ + +/** value PI in a phase16 expression */ +#define bbs_M_PI_16 32768 + +/** value PI/2 in a phase16 expression */ +#define bbs_M_PI_2_16 16384 + +/** value PI/4 in a phase16 expression */ +#define bbs_M_PI_4_16 8192 + +/** value PI in a phase8 expression */ +#define bbs_M_PI_8 128 + +/** value PI/2 in a phase8 expression */ +#define bbs_M_PI_2_8 64 + +/** value ( 32768 / PI ) in the format 14.1 */ +#define bbs_PHASE_MAX_BY_PI 20861 + +/** sine interpolation method */ +#define bbs_SIN_INTERPOLATION_METHOD_2 + +/* ---- object definition -------------------------------------------------- */ + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** + * Computes sine of a phase + * The return value has the format 8.24 + * The function approximates ( int32 )( sin( ( M_PI * phaseA ) / ( 1<<15 ) ) * ( 1<<24 ) ) + * Max error: 8.5E-5 (METHOD1); 7.0E-5 (METHOD2) + * Std error: 4.4E-5 (METHOD1); 3.2E-5 (METHOD2) + */ +int32 bbs_sin32( phase16 phaseA ); + +/** + * Computes cosine of a phase + * The return value has the format 8.24 + * The function approximates ( int32 )( cos( ( M_PI * phaseA ) / ( 1<<15 ) ) * ( 1<<24 ) ) + * Max error: 8.5E-5 (METHOD1); 7.0E-5 (METHOD2) + * Std error: 4.4E-5 (METHOD1); 3.2E-5 (METHOD2) + */ +int32 bbs_cos32( phase16 phaseA ); + +/** + * Computes sine of a phase + * The return value has the format 2.14 + * see sin32 for details + */ +int16 bbs_sin16( phase16 phaseA ); + +/** + * Computes cosine of a phase + * The return value has the format 2.14 + * see cos32 for details + */ +int16 bbs_cos16( phase16 phaseA ); + +/** + * Computes arcus tangens between [0,1[, where valA has the format 16.16 + * The function approximates ( int16 )( atan( double( valA ) / ( ( 1 << 16 ) ) / M_PI ) * ( 1 << 15 ) ) + * Max error: 5.1E-5 PI + * Std error: 2.7E-5 PI + */ +phase16 bbs_atan16( uint32 valA ); + +/** + * Computes phase from a 2d vector as angle enclosed between vector and (0,0). + * It is vec = ( cos( angle ), sin( angle ) ); + * Max error: 5.4E-5 PI + * Std error: 2.9E-5 PI + */ +phase16 bbs_phase16( int32 xA, int32 yA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +#endif /* bbs_PHASE_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/String.c b/Embedded/common/src/b_BasicEm/String.c new file mode 100644 index 0000000..edd51e0 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/String.c @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/String.h" +/* +#include <stdlib.h> +*/ + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +char* bbs_strcpy( char* dstA, const char* srcA ) +{ + const char* srcL = srcA; + char* dstL = dstA; + while( ( *dstL++ = *srcL++ ) != 0 ); + return dstA; +} + +/* ------------------------------------------------------------------------- */ + +char* bbs_strncpy( char* dstA, const char* srcA, uint32 sizeA ) +{ + uint32 iL; + for( iL = 0; iL < sizeA; iL++ ) + { + if( ( dstA[ iL ] = srcA[ iL ] ) == 0 ) break; + } + if( iL == sizeA && sizeA > 0 ) dstA[ iL - 1 ] = 0; + return dstA; +} + +/* ------------------------------------------------------------------------- */ + +char* bbs_strcat( char* dstA, const char* srcA ) +{ + const char* srcL = srcA; + char* dstL = dstA; + while( *dstL != 0 ) dstL++; + while( ( *dstL++ = *srcL++ ) != 0 ); + return dstA; +} + +/* ------------------------------------------------------------------------- */ + +char* bbs_strncat( char* dstA, const char* srcA, uint32 sizeA ) +{ + uint32 iL; + for( iL = 0; iL < sizeA; iL++ ) + { + if( dstA[ iL ] == 0 ) break; + } + + for( ; iL < sizeA; iL++ ) + { + if( ( dstA[ iL ] = srcA[ iL ] ) == 0 ) break; + } + + if( iL == sizeA && sizeA > 0 ) dstA[ iL - 1 ] = 0; + + return dstA; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_strlen( const char* strA ) +{ + uint32 iL = 0; + while( strA[ iL++ ] != 0 ); + return iL - 1; +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_strequal( const char* str1A, const char* str2A ) +{ + const char* str1L = str1A; + const char* str2L = str2A; + + if( str1L == NULL && str2L == NULL ) return TRUE; + if( str1L == NULL || str2L == NULL ) return FALSE; + + while( ( *str1L != 0 ) && ( *str2L != 0 ) ) + { + if( *str1L != *str2L ) break; + str1L++; + str2L++; + } + + return *str1L == *str2L; +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_strmatch( const char* str1A, const char* str2A ) +{ + const char* str1L = str1A; + const char* str2L = str2A; + + if( str1L == NULL || str2L == NULL ) return TRUE; + + while( ( *str1L != 0 ) && ( *str2L != 0 ) ) + { + if( *str1L != *str2L ) break; + str1L++; + str2L++; + } + + if( *str1L == 0 || *str2L == 0 ) return TRUE; + + return *str1L == *str2L; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_snprintf( char* bufA, uint32 bufSizeA, const char* formatA, ... ) +{ + uint32 sizeL; + va_list argsL; + va_start( argsL, formatA ); + sizeL = bbs_vsnprintf( bufA, bufSizeA, formatA, argsL ); + va_end( argsL ); + return sizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* converts number to string without 0 termination - returns number of characters written */ +uint32 bbs_cString( int32 valA, char* dstA, uint32 bufSizeA ) +{ + uint32 valL = ( valA < 0 ) ? -valA : valA; + uint32 iL = 0; + uint32 digitsL = 0; + if( valA < 0 ) + { + if( iL < bufSizeA ) dstA[ iL++ ] = '-'; + } + + /* count #digits */ + if( valL == 0 ) + { + iL++; + } + else + { + while( valL > 0 ) + { + iL++; + valL /= 10; + } + } + + digitsL = ( iL > bufSizeA ) ? bufSizeA : iL; + + valL = ( valA < 0 ) ? -valA : valA; + + if( valL == 0 ) + { + if( iL < bufSizeA ) dstA[ --iL ] = '0'; + } + else + { + while( valL > 0 ) + { + if( iL < bufSizeA ) dstA[ --iL ] = '0' + ( valL % 10 ); + valL /= 10; + } + } + + return digitsL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_vsnprintf( char* bufA, uint32 bufSizeA, const char* formatA, va_list argsA ) +{ + const char* fpL = formatA; + uint32 iL = 0; + + while( *fpL != 0 ) + { + if( *fpL == '%' ) + { + if( *( fpL + 1 ) == 'i' || *( fpL + 1 ) == 'd' ) + { + int valL = va_arg( argsA, int ); + if( iL < bufSizeA ) + { + iL += bbs_cString( valL, bufA + iL, bufSizeA - iL ); + } + fpL += 2; + } + else if( *( fpL + 1 ) == 's' ) + { + const char* stringL = va_arg( argsA, char* ); + if( iL < bufSizeA ) + { + bufA[ iL ] = 0; + bbs_strncat( bufA + iL, stringL, bufSizeA - iL ); + iL += bbs_strlen( stringL ); + } + fpL += 2; + } + else if( *( fpL + 1 ) == '%' ) + { + if( iL < bufSizeA ) bufA[ iL++ ] = '%'; + fpL++; + } + else + { + if( iL < bufSizeA ) bufA[ iL++ ] = *fpL; + fpL++; + } + } + else + { + if( iL < bufSizeA ) bufA[ iL++ ] = *fpL; + fpL++; + } + } + + if( iL < bufSizeA ) + { + bufA[ iL ] = 0; + } + else if( bufSizeA > 0 ) + { + bufA[ bufSizeA - 1 ] = 0; + } + + return iL; +} + +/* ------------------------------------------------------------------------- */ + +int32 bbs_atoi( const char* strA ) +{ + int32 valL = 0; + int16 signL = 1; + uint16 iL = 0, lenL = bbs_strlen( strA ); + + while( iL < lenL && strA[ iL ] == ' ' ) iL++; + if( strA[ iL ] == '-' ) + { + signL = -1; + iL++; + } + while( iL < lenL && strA[ iL ] == ' ' ) iL++; + while( iL < lenL && strA[ iL ] >= '0' && strA[ iL ] <= '9' ) + { + valL = valL * 10 + ( strA[ iL ] - '0' ); + iL++; + } + return valL * signL; +} + +/* ------------------------------------------------------------------------- */ + diff --git a/Embedded/common/src/b_BasicEm/String.h b/Embedded/common/src/b_BasicEm/String.h new file mode 100644 index 0000000..ad2a0a2 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/String.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_STRING_EM_H +#define bbs_STRING_EM_H + +/** + * This file contains string related functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include <stdarg.h> + +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** copies a string from srcA to dstA; returns dstA */ +char* bbs_strcpy( char* dstA, const char* srcA ); + +/** copies sizeA caracters from from srcA to dstA; returns dstA */ +char* bbs_strncpy( char* dstA, const char* srcA, uint32 sizeA ); + +/** adds a string srcA to string dstA; returns dstA */ +char* bbs_strcat( char* dstA, const char* srcA ); + +/** adds sizeA characters from srcA to string dstA; returns dstA */ +char* bbs_strncat( char* dstA, const char* srcA, uint32 sizeA ); + +/** returns number of characters in string excluding terminating 0 */ +uint32 bbs_strlen( const char* strA ); + +/** returns true if both strings are equal */ +flag bbs_strequal( const char* str1A, const char* str2A ); + +/** returns true if all characters of the smaller of both string are equal with the other string */ +flag bbs_strmatch( const char* str1A, const char* str2A ); + +/** writes a formated string to buffer with size limitation; returns number of characters written + * Not all possible format types of stdlib function snprintf are handled in this function + */ +uint32 bbs_snprintf( char* dstA, uint32 bufSizeA, const char* formatA, ... ); + +/** writes a formated string to buffer with size limitation; returns number of characters written + * Not all possible format types of stdlib function vsnprintf are handled in this function + */ +uint32 bbs_vsnprintf( char* dstA, uint32 bufSizeA, const char* formatA, va_list argsA ); + +/** converts a string to an integer */ +int32 bbs_atoi( const char* strA ); + +#endif /* bbs_STRING_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/UInt16Arr.c b/Embedded/common/src/b_BasicEm/UInt16Arr.c new file mode 100644 index 0000000..29bb634 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/UInt16Arr.c @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/UInt16Arr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt16Arr_init( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt16Arr_exit( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt16Arr_copy( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + const struct bbs_UInt16Arr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_UInt16Arr_copy( ... ):\n" + "Unsufficient allocated memory in destination array." ); + return; + } +#endif + bbs_UInt16Arr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy16( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE * bbs_SIZEOF16( uint16 ) ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_UInt16Arr_equal( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + const struct bbs_UInt16Arr* srcPtrA ) +{ + uint32 iL; + const uint16* ptr1L = ptrA->arrPtrE; + const uint16* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( *ptr1L++ != *ptr2L++ ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt16Arr_checkSum( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + uint32 startIndexA, uint32 sizeA ) +{ + uint32 iL; + uint32 sumL = 0; + const uint16* ptrL = ptrA->arrPtrE + startIndexA; + for( iL = sizeA; iL > 0; iL-- ) + { + sumL += *ptrL++; + } + return sumL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt16Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + uint32 sizeA ) +{ + return sizeA * bbs_SIZEOF16( uint16 ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt16Arr_size( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_UInt16Arr_size( struct bbs_UInt16Arr*, uint32 sizeA ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt16Arr_create( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->sizeE == sizeA ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_UInt16Arr_size( cpA, ptrA, sizeA ); + } + else + { + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( uint16 ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeA; + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt16Arr_memSize( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE * bbs_SIZEOF16( uint16 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt16Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_UInt16Arr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt16Arr_memRead( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_UInt16Arr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + + if( memSizeL != bbs_UInt16Arr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_UInt16Arr_memRead( const struct bbs_UInt16Arr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt16Arr_fill( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + uint16 valA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + ptrA->arrPtrE[ iL ] = valA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/UInt16Arr.h b/Embedded/common/src/b_BasicEm/UInt16Arr.h new file mode 100644 index 0000000..0de1a2e --- /dev/null +++ b/Embedded/common/src/b_BasicEm/UInt16Arr.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_UINT16ARR_EM_H +#define bbs_UINT16ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** byte array */ +struct bbs_UInt16Arr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of uint16 */ + uint16* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_UInt16Arr */ +void bbs_UInt16Arr_init( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA ); + +/** frees bbs_UInt16Arr */ +void bbs_UInt16Arr_exit( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_UInt16Arr_copy( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + const struct bbs_UInt16Arr* srcPtrA ); + +/** equal operator */ +flag bbs_UInt16Arr_equal( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + const struct bbs_UInt16Arr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** computes check sum for bbs_UInt16Arr (for debugging) */ +uint32 bbs_UInt16Arr_checkSum( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + uint32 startIndexA, uint32 sizeA ); + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_UInt16Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bbs_UInt16Arr */ +void bbs_UInt16Arr_create( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_UInt16Arr_size( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_UInt16Arr_memSize( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bbs_UInt16Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_UInt16Arr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bbs_UInt16Arr_memRead( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** fills array with a value */ +void bbs_UInt16Arr_fill( struct bbs_Context* cpA, + struct bbs_UInt16Arr* ptrA, + uint16 valA ); + +#endif /* bbs_UINT16ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/UInt32Arr.c b/Embedded/common/src/b_BasicEm/UInt32Arr.c new file mode 100644 index 0000000..90d27c6 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/UInt32Arr.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/UInt32Arr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt32Arr_init( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt32Arr_exit( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt32Arr_copy( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + const struct bbs_UInt32Arr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_UInt32Arr_copy(...):\n" + "Unsufficient allocated memory in destination array." ); + return; + } +#endif + bbs_UInt32Arr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy32( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE * bbs_SIZEOF32( uint32 ) ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_UInt32Arr_equal( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA, + const struct bbs_UInt32Arr* srcPtrA ) +{ + uint32 iL; + const uint32* ptr1L = ptrA->arrPtrE; + const uint32* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( *ptr1L++ != *ptr2L++ ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt32Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA, + uint32 sizeA ) +{ + return sizeA * bbs_SIZEOF16( uint32 ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt32Arr_create( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->sizeE == sizeA ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_UInt32Arr_size( cpA, ptrA, sizeA ); + } + else + { + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( uint32 ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeA; + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt32Arr_size( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_UInt32Arr_size( struct bbs_UInt32Arr*, uint32 ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt32Arr_memSize( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE * bbs_SIZEOF16( uint32 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt32Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_UInt32Arr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite32Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt32Arr_memRead( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_UInt32Arr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead32Arr( cpA, ptrA->arrPtrE, ptrA->sizeE, memPtrA ); + + if( memSizeL != bbs_UInt32Arr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_UInt32Arr_memRead( const struct bbs_UInt32Arr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt32Arr_fill( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + uint32 valA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + ptrA->arrPtrE[ iL ] = valA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/UInt32Arr.h b/Embedded/common/src/b_BasicEm/UInt32Arr.h new file mode 100644 index 0000000..f87875f --- /dev/null +++ b/Embedded/common/src/b_BasicEm/UInt32Arr.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_UINT32ARR_EM_H +#define bbs_UINT32ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** byte array */ +struct bbs_UInt32Arr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of uint32 */ + uint32* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_UInt32Arr */ +void bbs_UInt32Arr_init( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA ); + +/** frees bbs_UInt32Arr */ +void bbs_UInt32Arr_exit( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_UInt32Arr_copy( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + const struct bbs_UInt32Arr* srcPtrA ); + +/** equal operator */ +flag bbs_UInt32Arr_equal( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA, + const struct bbs_UInt32Arr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_UInt32Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bbs_UInt32Arr */ +void bbs_UInt32Arr_create( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_UInt32Arr_size( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_UInt32Arr_memSize( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bbs_UInt32Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_UInt32Arr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bbs_UInt32Arr_memRead( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** fills array with a value */ +void bbs_UInt32Arr_fill( struct bbs_Context* cpA, + struct bbs_UInt32Arr* ptrA, + uint32 valA ); + +#endif /* bbs_UINT32ARR_EM_H */ + diff --git a/Embedded/common/src/b_BasicEm/UInt8Arr.c b/Embedded/common/src/b_BasicEm/UInt8Arr.c new file mode 100644 index 0000000..45ef97c --- /dev/null +++ b/Embedded/common/src/b_BasicEm/UInt8Arr.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/UInt8Arr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt8Arr_init( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA ) +{ + ptrA->arrPtrE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->mspE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt8Arr_exit( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->arrPtrE ); + ptrA->arrPtrE = NULL; + ptrA->mspE = NULL; + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt8Arr_copy( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + const struct bbs_UInt8Arr* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->allocatedSizeE ) + { + bbs_ERROR0( "void bbs_UInt8Arr_copy(...):\n" + "Unsufficient allocated memory in destination array." ); + return; + } +#endif + bbs_UInt8Arr_size( cpA, ptrA, srcPtrA->sizeE ); + bbs_memcpy16( ptrA->arrPtrE, srcPtrA->arrPtrE, srcPtrA->sizeE >> 1 ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbs_UInt8Arr_equal( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA, + const struct bbs_UInt8Arr* srcPtrA ) +{ + long iL; + const uint8* ptr1L = ptrA->arrPtrE; + const uint8* ptr2L = srcPtrA->arrPtrE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( *ptr1L++ != *ptr2L++ ) return FALSE; + } + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt8Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA, + uint32 sizeA ) +{ + return ( sizeA >> 1 ) + bbs_MEM_BLOCK_OVERHD; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt8Arr_create( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->sizeE == sizeA ) return; + if( ptrA->arrPtrE != 0 ) + { + bbs_UInt8Arr_size( cpA, ptrA, sizeA ); + } + else + { + /* if size is odd increase by 1 byte */ + uint32 sizeL = sizeA; + if( ( sizeL & 1 ) != 0 ) sizeL++; + + ptrA->arrPtrE = bbs_MemSeg_alloc( cpA, mspA, sizeL >> 1 ); + if( bbs_Context_error( cpA ) ) return; + ptrA->allocatedSizeE = sizeL; + + ptrA->sizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt8Arr_size( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR1( "void bbs_UInt8Arr_size( struct bbs_UInt8Arr*, uint32 ):\n" + "Unsufficient allocated memory (allocatedSizeE = '%i')", + ptrA->allocatedSizeE ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt8Arr_memSize( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + bbs_SIZEOF16( ptrA->sizeE ) + + ptrA->sizeE / 2; /* int8 = 0.5 word size*/ +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt8Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbs_UInt8Arr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE / 2, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbs_UInt8Arr_memRead( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, sizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + bbs_UInt8Arr_create( cpA, ptrA, sizeL, mspA ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->arrPtrE, ptrA->sizeE / 2, memPtrA ); + + if( memSizeL != bbs_UInt8Arr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbs_UInt8Arr_memRead( const struct bbs_UInt8Arr*, const uint16* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbs_UInt8Arr_fill( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + uint8 valA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + ptrA->arrPtrE[ iL ] = valA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_BasicEm/UInt8Arr.h b/Embedded/common/src/b_BasicEm/UInt8Arr.h new file mode 100644 index 0000000..01bdc88 --- /dev/null +++ b/Embedded/common/src/b_BasicEm/UInt8Arr.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbs_UINT8ARR_EM_H +#define bbs_UINT8ARR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** byte array */ +struct bbs_UInt8Arr +{ + + /* ---- private data --------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to array of bytes */ + uint8* arrPtrE; + + /** current size */ + uint32 sizeE; + + /** allocated size */ + uint32 allocatedSizeE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbs_UInt8Arr */ +void bbs_UInt8Arr_init( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA ); + +/** destructs bbs_UInt8Arr */ +void bbs_UInt8Arr_exit( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbs_UInt8Arr_copy( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + const struct bbs_UInt8Arr* srcPtrA ); + +/** equal operator */ +flag bbs_UInt8Arr_equal( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA, + const struct bbs_UInt8Arr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bbs_UInt8Arr_heapSize( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bbs_UInt8Arr */ +void bbs_UInt8Arr_create( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** sets array size */ +void bbs_UInt8Arr_size( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bbs_UInt8Arr_memSize( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bbs_UInt8Arr_memWrite( struct bbs_Context* cpA, + const struct bbs_UInt8Arr* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bbs_UInt8Arr_memRead( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** fills array with a value */ +void bbs_UInt8Arr_fill( struct bbs_Context* cpA, + struct bbs_UInt8Arr* ptrA, + uint8 valA ); + +#endif /* bbs_UINT8ARR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/BitParam.c b/Embedded/common/src/b_BitFeatureEm/BitParam.c new file mode 100644 index 0000000..e8997b1 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/BitParam.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BitFeatureEm/BitParam.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_BitParam_init( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA ) +{ + ptrA->innerRadiusE = 0; + ptrA->outerRadiusE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_BitParam_exit( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA ) +{ + ptrA->innerRadiusE = 0; + ptrA->outerRadiusE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_BitParam_copy( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA, + const struct bbf_BitParam* srcPtrA ) +{ + ptrA->innerRadiusE = srcPtrA->innerRadiusE; + ptrA->outerRadiusE = srcPtrA->outerRadiusE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_BitParam_equal( struct bbs_Context* cpA, + const struct bbf_BitParam* ptrA, + const struct bbf_BitParam* srcPtrA ) +{ + if( ptrA->innerRadiusE != srcPtrA->innerRadiusE ) return FALSE; + if( ptrA->outerRadiusE != srcPtrA->outerRadiusE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_BitParam_memSize( struct bbs_Context* cpA, + const struct bbf_BitParam* ptrA ) +{ + uint32 memSizeL = 0; + memSizeL += bbs_SIZEOF16( ptrA->innerRadiusE ); + memSizeL += bbs_SIZEOF16( ptrA->outerRadiusE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_BitParam_memWrite( struct bbs_Context* cpA, + const struct bbf_BitParam* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite32( &ptrA->innerRadiusE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->outerRadiusE, memPtrA ); + return bbf_BitParam_memSize( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_BitParam_memRead( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA, + const uint16* memPtrA ) +{ + memPtrA += bbs_memRead32( &ptrA->innerRadiusE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->outerRadiusE, memPtrA ); + return bbf_BitParam_memSize( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/BitParam.h b/Embedded/common/src/b_BitFeatureEm/BitParam.h new file mode 100644 index 0000000..c138b2a --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/BitParam.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_BIT_PARAM_EM_H +#define bbf_BIT_PARAM_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** parameters for bit generation. */ +struct bbf_BitParam +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** outer radius of filter block */ + uint32 outerRadiusE; + + /** inner radius of filter block */ + uint32 innerRadiusE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_BitParam */ +void bbf_BitParam_init( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA ); + +/** resets bbf_BitParam */ +void bbf_BitParam_exit( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_BitParam_copy( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA, + const struct bbf_BitParam* srcPtrA ); + +/** equal operator */ +flag bbf_BitParam_equal( struct bbs_Context* cpA, + const struct bbf_BitParam* ptrA, + const struct bbf_BitParam* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_BitParam_memSize( struct bbs_Context* cpA, + const struct bbf_BitParam* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_BitParam_memWrite( struct bbs_Context* cpA, + const struct bbf_BitParam* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_BitParam_memRead( struct bbs_Context* cpA, + struct bbf_BitParam* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +#endif /* bbf_BIT_PARAM_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Feature.c b/Embedded/common/src/b_BitFeatureEm/Feature.c new file mode 100644 index 0000000..2185e90 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Feature.c @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BitFeatureEm/Feature.h" + +#include "b_BitFeatureEm/Sequence.h" +#include "b_BitFeatureEm/I04Dns2x2Ftr.h" +#include "b_BitFeatureEm/I04Tld2x4Ftr.h" +#include "b_BitFeatureEm/I04Dns2x4Ftr.h" +#include "b_BitFeatureEm/L01Tld2x4Ftr.h" +#include "b_BitFeatureEm/L01Dns2x4Ftr.h" +#include "b_BitFeatureEm/L04Dns2x4Ftr.h" +#include "b_BitFeatureEm/L04Dns3x3Ftr.h" +#include "b_BitFeatureEm/L06Dns3x3Ftr.h" +#include "b_BitFeatureEm/L06Dns4x4Ftr.h" +#include "b_BitFeatureEm/L06DnsNx4x4Ftr.h" +#include "b_BitFeatureEm/L01Tld1x1Ftr.h" +#include "b_BitFeatureEm/L04Tld2x4Ftr.h" +#include "b_BitFeatureEm/L04Dns2x2Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Feature_init( struct bbs_Context* cpA, + struct bbf_Feature* ptrA ) +{ + ptrA->typeE = 0; + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->vpActivityE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Feature_exit( struct bbs_Context* cpA, + struct bbf_Feature* ptrA ) +{ + ptrA->typeE = 0; + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->vpActivityE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Feature_copy( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + const struct bbf_Feature* srcPtrA ) +{ + ptrA->typeE = srcPtrA->typeE; + ptrA->patchWidthE = srcPtrA->patchWidthE; + ptrA->patchHeightE = srcPtrA->patchHeightE; + ptrA->vpActivityE = srcPtrA->vpActivityE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_Feature_equal( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA, + const struct bbf_Feature* srcPtrA ) +{ + + if( ptrA->typeE != srcPtrA->typeE ) return FALSE; + if( ptrA->patchWidthE != srcPtrA->patchWidthE ) return FALSE; + if( ptrA->patchHeightE != srcPtrA->patchHeightE ) return FALSE; + if( ptrA->vpActivityE != srcPtrA->vpActivityE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Feature_memSize( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA ) +{ + uint32 memSizeL = 0; + memSizeL += bbs_SIZEOF16( ptrA->typeE ); + memSizeL += bbs_SIZEOF16( ptrA->patchWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->patchHeightE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Feature_memWrite( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_Feature_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &ptrA->typeE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Feature_memRead( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &ptrA->typeE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA ); + return bbf_Feature_memSize( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_featureInit( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + enum bbf_FeatureType typeA ) +{ + switch( typeA ) + { + case bbf_FT_SEQUENCE: bbf_Sequence_init( cpA, ( struct bbf_Sequence* )ptrA ); return; + case bbf_FT_I04_DNS_2X2_FTR: bbf_I04Dns2x2Ftr_init( cpA, ( struct bbf_I04Dns2x2Ftr* )ptrA ); return; + case bbf_FT_I04_TLD_2X4_FTR: bbf_I04Tld2x4Ftr_init( cpA, ( struct bbf_I04Tld2x4Ftr* )ptrA ); return; + case bbf_FT_I04_DNS_2X4_FTR: bbf_I04Dns2x4Ftr_init( cpA, ( struct bbf_I04Dns2x4Ftr* )ptrA ); return; + case bbf_FT_L01_TLD_2X4_FTR: bbf_L01Tld2x4Ftr_init( cpA, ( struct bbf_L01Tld2x4Ftr* )ptrA ); return; + case bbf_FT_L01_DNS_2X4_FTR: bbf_L01Dns2x4Ftr_init( cpA, ( struct bbf_L01Dns2x4Ftr* )ptrA ); return; + case bbf_FT_L04_DNS_2X4_FTR: bbf_L04Dns2x4Ftr_init( cpA, ( struct bbf_L04Dns2x4Ftr* )ptrA ); return; + case bbf_FT_L04_DNS_3X3_FTR: bbf_L04Dns3x3Ftr_init( cpA, ( struct bbf_L04Dns3x3Ftr* )ptrA ); return; + case bbf_FT_L06_DNS_3X3_FTR: bbf_L06Dns3x3Ftr_init( cpA, ( struct bbf_L06Dns3x3Ftr* )ptrA ); return; + case bbf_FT_L06_DNS_4X4_FTR: bbf_L06Dns4x4Ftr_init( cpA, ( struct bbf_L06Dns4x4Ftr* )ptrA ); return; + case bbf_FT_L06_DNS_NX4X4_FTR: bbf_L06DnsNx4x4Ftr_init( cpA, ( struct bbf_L06DnsNx4x4Ftr* )ptrA ); return; + case bbf_FT_L01_TLD_1X1_FTR: bbf_L01Tld1x1Ftr_init( cpA, ( struct bbf_L01Tld1x1Ftr* )ptrA ); return; + case bbf_FT_L04_TLD_2X4_FTR: bbf_L04Tld2x4Ftr_init( cpA, ( struct bbf_L04Tld2x4Ftr* )ptrA ); return; + case bbf_FT_L04_DNS_2X2_FTR: bbf_L04Dns2x2Ftr_init( cpA, ( struct bbf_L04Dns2x2Ftr* )ptrA ); return; + + default: bbs_ERROR0( "bbf_featureInit: invalid type" ); + } +} + +/* ------------------------------------------------------------------------- */ + +void bbf_featureExit( struct bbs_Context* cpA, + struct bbf_Feature* ptrA ) +{ + switch( ptrA->typeE ) + { + case bbf_FT_SEQUENCE: bbf_Sequence_exit( cpA, ( struct bbf_Sequence* )ptrA ); return; + case bbf_FT_I04_DNS_2X2_FTR: bbf_I04Dns2x2Ftr_exit( cpA, ( struct bbf_I04Dns2x2Ftr* )ptrA ); return; + case bbf_FT_I04_TLD_2X4_FTR: bbf_I04Tld2x4Ftr_exit( cpA, ( struct bbf_I04Tld2x4Ftr* )ptrA ); return; + case bbf_FT_I04_DNS_2X4_FTR: bbf_I04Dns2x4Ftr_exit( cpA, ( struct bbf_I04Dns2x4Ftr* )ptrA ); return; + case bbf_FT_L01_TLD_2X4_FTR: bbf_L01Tld2x4Ftr_exit( cpA, ( struct bbf_L01Tld2x4Ftr* )ptrA ); return; + case bbf_FT_L01_DNS_2X4_FTR: bbf_L01Dns2x4Ftr_exit( cpA, ( struct bbf_L01Dns2x4Ftr* )ptrA ); return; + case bbf_FT_L04_DNS_2X4_FTR: bbf_L04Dns2x4Ftr_exit( cpA, ( struct bbf_L04Dns2x4Ftr* )ptrA ); return; + case bbf_FT_L04_DNS_3X3_FTR: bbf_L04Dns3x3Ftr_exit( cpA, ( struct bbf_L04Dns3x3Ftr* )ptrA ); return; + case bbf_FT_L06_DNS_3X3_FTR: bbf_L06Dns3x3Ftr_exit( cpA, ( struct bbf_L06Dns3x3Ftr* )ptrA ); return; + case bbf_FT_L06_DNS_4X4_FTR: bbf_L06Dns4x4Ftr_exit( cpA, ( struct bbf_L06Dns4x4Ftr* )ptrA ); return; + case bbf_FT_L06_DNS_NX4X4_FTR: bbf_L06DnsNx4x4Ftr_exit( cpA, ( struct bbf_L06DnsNx4x4Ftr* )ptrA ); return; + case bbf_FT_L01_TLD_1X1_FTR: bbf_L01Tld1x1Ftr_exit( cpA, ( struct bbf_L01Tld1x1Ftr* )ptrA ); return; + case bbf_FT_L04_TLD_2X4_FTR: bbf_L04Tld2x4Ftr_exit( cpA, ( struct bbf_L04Tld2x4Ftr* )ptrA ); return; + case bbf_FT_L04_DNS_2X2_FTR: bbf_L04Dns2x2Ftr_exit( cpA, ( struct bbf_L04Dns2x2Ftr* )ptrA ); return; + default: bbs_ERROR0( "bbf_featureExit: invalid type" ); + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_featureMemSize( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA ) +{ + switch( ptrA->typeE ) + { + case bbf_FT_SEQUENCE: return bbf_Sequence_memSize( cpA, ( struct bbf_Sequence* )ptrA ); + case bbf_FT_I04_DNS_2X2_FTR: return bbf_I04Dns2x2Ftr_memSize( cpA, ( struct bbf_I04Dns2x2Ftr* )ptrA ); + case bbf_FT_I04_TLD_2X4_FTR: return bbf_I04Tld2x4Ftr_memSize( cpA, ( struct bbf_I04Tld2x4Ftr* )ptrA ); + case bbf_FT_I04_DNS_2X4_FTR: return bbf_I04Dns2x4Ftr_memSize( cpA, ( struct bbf_I04Dns2x4Ftr* )ptrA ); + case bbf_FT_L01_TLD_2X4_FTR: return bbf_L01Tld2x4Ftr_memSize( cpA, ( struct bbf_L01Tld2x4Ftr* )ptrA ); + case bbf_FT_L01_DNS_2X4_FTR: return bbf_L01Dns2x4Ftr_memSize( cpA, ( struct bbf_L01Dns2x4Ftr* )ptrA ); + case bbf_FT_L04_DNS_2X4_FTR: return bbf_L04Dns2x4Ftr_memSize( cpA, ( struct bbf_L04Dns2x4Ftr* )ptrA ); + case bbf_FT_L04_DNS_3X3_FTR: return bbf_L04Dns3x3Ftr_memSize( cpA, ( struct bbf_L04Dns3x3Ftr* )ptrA ); + case bbf_FT_L06_DNS_3X3_FTR: return bbf_L06Dns3x3Ftr_memSize( cpA, ( struct bbf_L06Dns3x3Ftr* )ptrA ); + case bbf_FT_L06_DNS_4X4_FTR: return bbf_L06Dns4x4Ftr_memSize( cpA, ( struct bbf_L06Dns4x4Ftr* )ptrA ); + case bbf_FT_L06_DNS_NX4X4_FTR: return bbf_L06DnsNx4x4Ftr_memSize( cpA, ( struct bbf_L06DnsNx4x4Ftr* )ptrA ); + case bbf_FT_L01_TLD_1X1_FTR: return bbf_L01Tld1x1Ftr_memSize( cpA, ( struct bbf_L01Tld1x1Ftr* )ptrA ); + case bbf_FT_L04_TLD_2X4_FTR: return bbf_L04Tld2x4Ftr_memSize( cpA, ( struct bbf_L04Tld2x4Ftr* )ptrA ); + case bbf_FT_L04_DNS_2X2_FTR: return bbf_L04Dns2x2Ftr_memSize( cpA, ( struct bbf_L04Dns2x2Ftr* )ptrA ); + default: bbs_ERROR0( "bbf_featureExit: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_featureMemWrite( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA, uint16* memPtrA ) +{ + switch( ptrA->typeE ) + { + case bbf_FT_SEQUENCE: return bbf_Sequence_memWrite( cpA, ( struct bbf_Sequence* )ptrA, memPtrA ); + case bbf_FT_I04_DNS_2X2_FTR: return bbf_I04Dns2x2Ftr_memWrite( cpA, ( struct bbf_I04Dns2x2Ftr* )ptrA, memPtrA ); + case bbf_FT_I04_TLD_2X4_FTR: return bbf_I04Tld2x4Ftr_memWrite( cpA, ( struct bbf_I04Tld2x4Ftr* )ptrA, memPtrA ); + case bbf_FT_I04_DNS_2X4_FTR: return bbf_I04Dns2x4Ftr_memWrite( cpA, ( struct bbf_I04Dns2x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L01_TLD_2X4_FTR: return bbf_L01Tld2x4Ftr_memWrite( cpA, ( struct bbf_L01Tld2x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L01_DNS_2X4_FTR: return bbf_L01Dns2x4Ftr_memWrite( cpA, ( struct bbf_L01Dns2x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L04_DNS_2X4_FTR: return bbf_L04Dns2x4Ftr_memWrite( cpA, ( struct bbf_L04Dns2x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L04_DNS_3X3_FTR: return bbf_L04Dns3x3Ftr_memWrite( cpA, ( struct bbf_L04Dns3x3Ftr* )ptrA, memPtrA ); + case bbf_FT_L06_DNS_3X3_FTR: return bbf_L06Dns3x3Ftr_memWrite( cpA, ( struct bbf_L06Dns3x3Ftr* )ptrA, memPtrA ); + case bbf_FT_L06_DNS_4X4_FTR: return bbf_L06Dns4x4Ftr_memWrite( cpA, ( struct bbf_L06Dns4x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L06_DNS_NX4X4_FTR: return bbf_L06DnsNx4x4Ftr_memWrite( cpA, ( struct bbf_L06DnsNx4x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L01_TLD_1X1_FTR: return bbf_L01Tld1x1Ftr_memWrite( cpA, ( struct bbf_L01Tld1x1Ftr* )ptrA, memPtrA ); + case bbf_FT_L04_TLD_2X4_FTR: return bbf_L04Tld2x4Ftr_memWrite( cpA, ( struct bbf_L04Tld2x4Ftr* )ptrA, memPtrA ); + case bbf_FT_L04_DNS_2X2_FTR: return bbf_L04Dns2x2Ftr_memWrite( cpA, ( struct bbf_L04Dns2x2Ftr* )ptrA, memPtrA ); + default: bbs_ERROR0( "bbf_featureMemWrite: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_featureMemRead( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + switch( ptrA->typeE ) + { + case bbf_FT_SEQUENCE: return bbf_Sequence_memRead( cpA, ( struct bbf_Sequence* )ptrA, memPtrA, mtpA ); + case bbf_FT_I04_DNS_2X2_FTR: return bbf_I04Dns2x2Ftr_memRead( cpA, ( struct bbf_I04Dns2x2Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_I04_TLD_2X4_FTR: return bbf_I04Tld2x4Ftr_memRead( cpA, ( struct bbf_I04Tld2x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_I04_DNS_2X4_FTR: return bbf_I04Dns2x4Ftr_memRead( cpA, ( struct bbf_I04Dns2x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L01_TLD_2X4_FTR: return bbf_L01Tld2x4Ftr_memRead( cpA, ( struct bbf_L01Tld2x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L01_DNS_2X4_FTR: return bbf_L01Dns2x4Ftr_memRead( cpA, ( struct bbf_L01Dns2x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L04_DNS_2X4_FTR: return bbf_L04Dns2x4Ftr_memRead( cpA, ( struct bbf_L04Dns2x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L04_DNS_3X3_FTR: return bbf_L04Dns3x3Ftr_memRead( cpA, ( struct bbf_L04Dns3x3Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L06_DNS_3X3_FTR: return bbf_L06Dns3x3Ftr_memRead( cpA, ( struct bbf_L06Dns3x3Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L06_DNS_4X4_FTR: return bbf_L06Dns4x4Ftr_memRead( cpA, ( struct bbf_L06Dns4x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L06_DNS_NX4X4_FTR: return bbf_L06DnsNx4x4Ftr_memRead( cpA, ( struct bbf_L06DnsNx4x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L01_TLD_1X1_FTR: return bbf_L01Tld1x1Ftr_memRead( cpA, ( struct bbf_L01Tld1x1Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L04_TLD_2X4_FTR: return bbf_L04Tld2x4Ftr_memRead( cpA, ( struct bbf_L04Tld2x4Ftr* )ptrA, memPtrA, mtpA ); + case bbf_FT_L04_DNS_2X2_FTR: return bbf_L04Dns2x2Ftr_memRead( cpA, ( struct bbf_L04Dns2x2Ftr* )ptrA, memPtrA, mtpA ); + default: bbs_ERROR0( "bbf_featureMemRead: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_featureSizeOf16( struct bbs_Context* cpA, enum bbf_FeatureType typeA ) +{ + switch( typeA ) + { + case bbf_FT_SEQUENCE: return bbs_SIZEOF16( struct bbf_Sequence ); + case bbf_FT_I04_DNS_2X2_FTR: return bbs_SIZEOF16( struct bbf_I04Dns2x2Ftr ); + case bbf_FT_I04_TLD_2X4_FTR: return bbs_SIZEOF16( struct bbf_I04Tld2x4Ftr ); + case bbf_FT_I04_DNS_2X4_FTR: return bbs_SIZEOF16( struct bbf_I04Dns2x4Ftr ); + case bbf_FT_L01_TLD_2X4_FTR: return bbs_SIZEOF16( struct bbf_L01Tld2x4Ftr ); + case bbf_FT_L01_DNS_2X4_FTR: return bbs_SIZEOF16( struct bbf_L01Dns2x4Ftr ); + case bbf_FT_L04_DNS_2X4_FTR: return bbs_SIZEOF16( struct bbf_L04Dns2x4Ftr ); + case bbf_FT_L04_DNS_3X3_FTR: return bbs_SIZEOF16( struct bbf_L04Dns3x3Ftr ); + case bbf_FT_L06_DNS_3X3_FTR: return bbs_SIZEOF16( struct bbf_L06Dns3x3Ftr ); + case bbf_FT_L06_DNS_4X4_FTR: return bbs_SIZEOF16( struct bbf_L06Dns4x4Ftr ); + case bbf_FT_L06_DNS_NX4X4_FTR: return bbs_SIZEOF16( struct bbf_L06DnsNx4x4Ftr ); + case bbf_FT_L01_TLD_1X1_FTR: return bbs_SIZEOF16( struct bbf_L01Tld1x1Ftr ); + case bbf_FT_L04_TLD_2X4_FTR: return bbs_SIZEOF16( struct bbf_L04Tld2x4Ftr ); + case bbf_FT_L04_DNS_2X2_FTR: return bbs_SIZEOF16( struct bbf_L04Dns2x2Ftr ); + default: bbs_ERROR0( "bbf_featureSizeOf16: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Feature.h b/Embedded/common/src/b_BitFeatureEm/Feature.h new file mode 100644 index 0000000..dd77ede --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Feature.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_FEATURE_EM_H +#define bbf_FEATURE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +enum bbf_FeatureType +{ + bbf_FT_UNDEFINED = 0, + bbf_FT_SEQUENCE, + bbf_FT_I04_DNS_2X2_FTR, + bbf_FT_I04_TLD_2X4_FTR, + bbf_FT_I04_DNS_2X4_FTR, + bbf_FT_L01_TLD_2X4_FTR, + bbf_FT_L01_DNS_2X4_FTR, + bbf_FT_L04_DNS_2X4_FTR, + bbf_FT_L04_DNS_3X3_FTR, + bbf_FT_L06_DNS_3X3_FTR, + bbf_FT_L06_DNS_4X4_FTR, + bbf_FT_L06_DNS_NX4X4_FTR, + + bbf_FT_L01_TLD_1X1_FTR, + bbf_FT_L04_TLD_2X4_FTR, + bbf_FT_L04_DNS_2X2_FTR +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** base object for features (occurs as first element in all feature objects) */ +struct bbf_Feature +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** feature type */ + uint32 typeE; + + /** width of patch */ + uint32 patchWidthE; + + /** height of patch */ + uint32 patchHeightE; + + /* ---- virtual functions ---------------------------------------------- */ + + /** computes feature's activity (4.28) on the given patch */ + int32 ( *vpActivityE )( const struct bbf_Feature* ptrA, const uint32* patchA ); +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_Feature */ +void bbf_Feature_init( struct bbs_Context* cpA, + struct bbf_Feature* ptrA ); + +/** resets bbf_Feature */ +void bbf_Feature_exit( struct bbs_Context* cpA, + struct bbf_Feature* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_Feature_copy( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + const struct bbf_Feature* srcPtrA ); + +/** equal operator */ +flag bbf_Feature_equal( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA, + const struct bbf_Feature* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_Feature_memSize( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_Feature_memWrite( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_Feature_memRead( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** virtual init function */ +void bbf_featureInit( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + enum bbf_FeatureType typeA ); + +/** virtual exit function */ +void bbf_featureExit( struct bbs_Context* cpA, + struct bbf_Feature* ptrA ); + +/** virtual mem size function */ +uint32 bbf_featureMemSize( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA ); + +/** virtual mem write function */ +uint32 bbf_featureMemWrite( struct bbs_Context* cpA, + const struct bbf_Feature* ptrA, uint16* memPtrA ); + +/** virtual mem read function */ +uint32 bbf_featureMemRead( struct bbs_Context* cpA, + struct bbf_Feature* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/** virtual sizeof operator for 16bit units */ +uint32 bbf_featureSizeOf16( struct bbs_Context* cpA, enum bbf_FeatureType typeA ); + +#endif /* bbf_FEATURE_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Functions.c b/Embedded/common/src/b_BitFeatureEm/Functions.c new file mode 100644 index 0000000..b4d7051 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Functions.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BitFeatureEm/Functions.h" +#include "b_ImageEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +const uint16 bbf_bit8TblG[ 256 ] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Functions.h b/Embedded/common/src/b_BitFeatureEm/Functions.h new file mode 100644 index 0000000..eda972d --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Functions.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_FUNCTIONS_EM_H +#define bbf_FUNCTIONS_EM_H + +/** + * This files contains gerneral purpose functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_ImageEm/UInt32Image.h" +#include "b_ImageEm/UInt16ByteImage.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** table to quickly determine the number of set bits in an 8 bit variable */ +extern const uint16 bbf_bit8TblG[ 256 ]; + +/* ---- external functions ------------------------------------------------- */ + +/** sums up bits in 8 bit variable */ +#define bbf_BIT_SUM_8( vA ) ( bbf_bit8TblG[ vA ] ) + +/** sums up bits in 16 bit variable */ +#define bbf_BIT_SUM_16( vA ) ( bbf_bit8TblG[ vA & 0x00FF ] + bbf_bit8TblG[ ( vA >> 8 ) & 0x00FF ] ) + +/** sums up bits in 16 bit variable */ +#define bbf_BIT_SUM_32( vA ) ( bbf_bit8TblG[ vA & 0x00FF ] + bbf_bit8TblG[ ( vA >> 8 ) & 0x00FF ] + bbf_bit8TblG[ ( vA >> 16 ) & 0x00FF ] + bbf_bit8TblG[ ( vA >> 24 ) & 0x00FF ] ) + + +#endif /* bbf_FUNCTIONS_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.c b/Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.c new file mode 100644 index 0000000..835833a --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/I04Dns2x2Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Dns2x2Ftr_init( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_I04_DNS_2X2_FTR; + ptrA->baseE.vpActivityE = bbf_I04Dns2x2Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->ptnArrE ); + bbs_Int16Arr_init( cpA, &ptrA->tableE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Dns2x2Ftr_exit( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->ptnArrE ); + bbs_Int16Arr_exit( cpA, &ptrA->tableE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Dns2x2Ftr_copy( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA, + const struct bbf_I04Dns2x2Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->ptnArrE, &srcPtrA->ptnArrE ); + bbs_Int16Arr_copy( cpA, &ptrA->tableE, &srcPtrA->tableE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_I04Dns2x2Ftr_equal( struct bbs_Context* cpA, + const struct bbf_I04Dns2x2Ftr* ptrA, + const struct bbf_I04Dns2x2Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->ptnArrE, &srcPtrA->ptnArrE ) ) return FALSE; + if( !bbs_Int16Arr_equal( cpA, &ptrA->tableE, &srcPtrA->tableE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Dns2x2Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_I04Dns2x2Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->ptnArrE ); + memSizeL += bbs_Int16Arr_memSize( cpA, &ptrA->tableE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Dns2x2Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_I04Dns2x2Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_I04Dns2x2Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_I04_DNS_2X2_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->ptnArrE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->tableE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Dns2x2Ftr_memRead( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_I04_DNS_2X2_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->ptnArrE, memPtrA, espL ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->tableE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_I04Dns2x2Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_I04Dns2x2Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_I04Dns2x2Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_I04Dns2x2Ftr* ptrL = ( struct bbf_I04Dns2x2Ftr* )ptrA; + + uint32 iL; + + const uint32* ptnPtrL = ptrL->ptnArrE.arrPtrE; + const int16* tableL = ptrL->tableE.arrPtrE; + const uint32* patchL = patchA; + + int32 sumL = 0; + + uint32 wL = ptrL->baseE.patchWidthE - 1; + uint32 hL = ptrL->baseE.patchHeightE - 1; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + uint32 blocksL = ptrL->baseE.patchHeightE >> 2; /* number of 4 bit blocks */ + + if( hL == 31 ) + { + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL = ( patchL[ 0 ] ^ ptnPtrL[ 0 ] ) & + ( ( patchL[ 0 ] >> 1 ) ^ ptnPtrL[ 1 ] ) & + ( ( patchL[ 1 ] ) ^ ptnPtrL[ 2 ] ) & + ( ( patchL[ 1 ] >> 1 ) ^ ptnPtrL[ 3 ] ) & borderMaskL; + + patchL++; + + ptnPtrL += 4; + + sumL += tableL[ ( vL ) & 0x0F ]; + sumL += tableL[ 16 + ( ( vL >> 4 ) & 0x0F ) ]; + sumL += tableL[ 32 + ( ( vL >> 8 ) & 0x0F ) ]; + sumL += tableL[ 48 + ( ( vL >> 12 ) & 0x0F ) ]; + sumL += tableL[ 64 + ( ( vL >> 16 ) & 0x0F ) ]; + sumL += tableL[ 80 + ( ( vL >> 20 ) & 0x0F ) ]; + sumL += tableL[ 96 + ( ( vL >> 24 ) & 0x0F ) ]; + sumL += tableL[ 112 + ( ( vL >> 28 ) & 0x0F ) ]; + tableL += 128; + } + } + else + { + for( iL = 0; iL < wL; iL++ ) + { + uint32 jL; + uint32 vL = ( patchL[ 0 ] ^ ptnPtrL[ 0 ] ) & + ( ( patchL[ 0 ] >> 1 ) ^ ptnPtrL[ 1 ] ) & + ( ( patchL[ 1 ] ) ^ ptnPtrL[ 2 ] ) & + ( ( patchL[ 1 ] >> 1 ) ^ ptnPtrL[ 3 ] ) & borderMaskL; + + patchL++; + ptnPtrL += 4; + + for( jL = 0; jL < blocksL; jL++ ) + { + sumL += tableL[ vL & 0x0F ]; + vL >>= 4; + tableL += 16; + } + } + } + + return sumL * ( ptrL->activityFactorE >> 8 ) + ( ( sumL * ( int32 )( ptrL->activityFactorE & 0x0FF ) ) >> 8 ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.h b/Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.h new file mode 100644 index 0000000..f8888ae --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/I04Dns2x2Ftr.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_I04_DNS_2X2_FTR_EM_H +#define bbf_I04_DNS_2X2_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_I04_DNS_2X2_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_I04Dns2x2Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** pattern array */ + struct bbs_UInt32Arr ptnArrE; + + /** look up table of weights */ + struct bbs_Int16Arr tableE; + + /** factor to convert activity to proper range (.36) */ + int32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_I04Dns2x2Ftr */ +void bbf_I04Dns2x2Ftr_init( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA ); + +/** resets bbf_I04Dns2x2Ftr */ +void bbf_I04Dns2x2Ftr_exit( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_I04Dns2x2Ftr_copy( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA, + const struct bbf_I04Dns2x2Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_I04Dns2x2Ftr_equal( struct bbs_Context* cpA, + const struct bbf_I04Dns2x2Ftr* ptrA, + const struct bbf_I04Dns2x2Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_I04Dns2x2Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_I04Dns2x2Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_I04Dns2x2Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_I04Dns2x2Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_I04Dns2x2Ftr_memRead( struct bbs_Context* cpA, + struct bbf_I04Dns2x2Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_I04Dns2x2Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_I04_DNS_2X2_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.c new file mode 100644 index 0000000..d9eab5e --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/I04Dns2x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Dns2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_I04_DNS_2X4_FTR; + ptrA->baseE.vpActivityE = bbf_I04Dns2x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + bbs_Int16Arr_init( cpA, &ptrA->tableE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Dns2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + bbs_Int16Arr_exit( cpA, &ptrA->tableE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Dns2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA, + const struct bbf_I04Dns2x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + bbs_Int16Arr_copy( cpA, &ptrA->tableE, &srcPtrA->tableE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_I04Dns2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_I04Dns2x4Ftr* ptrA, + const struct bbf_I04Dns2x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( !bbs_Int16Arr_equal( cpA, &ptrA->tableE, &srcPtrA->tableE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Dns2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_I04Dns2x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_Int16Arr_memSize( cpA, &ptrA->tableE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Dns2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_I04Dns2x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_I04Dns2x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_I04_DNS_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->tableE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Dns2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_I04_DNS_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->tableE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_I04Dns2x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_I04Dns2x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_I04Dns2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_I04Dns2x4Ftr* ptrL = ( struct bbf_I04Dns2x4Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 1; + uint32 hL = ptrL->baseE.patchHeightE - 3; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + const int16* tableL = ptrL->tableE.arrPtrE; + + uint32 blocksL = ptrL->baseE.patchHeightE >> 2; + uint32 iL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + int32 sumL = 0; + + uint32 sL[ 8 ]; + uint32 mL[ 4 ]; + + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL = 0; + + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + sL[ 3 ] = ( ( s1L >> 3 ) ^ dataPtrL[ 3 ] ) & borderMaskL; + + sL[ 4 ] = ( ( s2L ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + sL[ 6 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s2L >> 3 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 3 features */ + mL[ 0 ] = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + + ( sL[ 2 ] & 0x11111111 ) + ( sL[ 3 ] & 0x11111111 ) + + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) ); + + mL[ 1 ] = ( ( sL[ 0 ] & 0x22222222 ) + ( sL[ 1 ] & 0x22222222 ) + + ( sL[ 2 ] & 0x22222222 ) + ( sL[ 3 ] & 0x22222222 ) + + ( sL[ 4 ] & 0x22222222 ) + ( sL[ 5 ] & 0x22222222 ) + + ( sL[ 6 ] & 0x22222222 ) + ( sL[ 7 ] & 0x22222222 ) ) >> 1; + + mL[ 2 ] = ( ( sL[ 0 ] & 0x44444444 ) + ( sL[ 1 ] & 0x44444444 ) + + ( sL[ 2 ] & 0x44444444 ) + ( sL[ 3 ] & 0x44444444 ) + + ( sL[ 4 ] & 0x44444444 ) + ( sL[ 5 ] & 0x44444444 ) + + ( sL[ 6 ] & 0x44444444 ) + ( sL[ 7 ] & 0x44444444 ) ) >> 2; + + mL[ 3 ] = ( ( sL[ 0 ] & 0x88888888 ) + ( sL[ 1 ] & 0x88888888 ) + + ( sL[ 2 ] & 0x88888888 ) + ( sL[ 3 ] & 0x88888888 ) + + ( sL[ 4 ] & 0x88888888 ) + ( sL[ 5 ] & 0x88888888 ) + + ( sL[ 6 ] & 0x88888888 ) + ( sL[ 7 ] & 0x88888888 ) ) >> 3; + + /* parallel comparison with thresholds and packing of results into bit array of size patchHeightE - 3 */ + vL |= ( ( mL[ 0 ] + dataPtrL[ 8 ] ) & 0x88888888 ) >> 3; + vL |= ( ( mL[ 1 ] + dataPtrL[ 9 ] ) & 0x88888888 ) >> 2; + vL |= ( ( mL[ 2 ] + dataPtrL[ 10 ] ) & 0x88888888 ) >> 1; + vL |= ( ( mL[ 3 ] + dataPtrL[ 11 ] ) & 0x88888888 ); + + vL = ( ~vL ) & 0x1FFFFFFF; + + /* parallel processing of weights (4 weights at a time) */ + if( hL == 29 ) + { + sumL += tableL[ ( vL ) & 0x0F ]; + sumL += tableL[ 16 + ( ( vL >> 4 ) & 0x0F ) ]; + sumL += tableL[ 32 + ( ( vL >> 8 ) & 0x0F ) ]; + sumL += tableL[ 48 + ( ( vL >> 12 ) & 0x0F ) ]; + sumL += tableL[ 64 + ( ( vL >> 16 ) & 0x0F ) ]; + sumL += tableL[ 80 + ( ( vL >> 20 ) & 0x0F ) ]; + sumL += tableL[ 96 + ( ( vL >> 24 ) & 0x0F ) ]; + sumL += tableL[ 112 + ( ( vL >> 28 ) & 0x0F ) ]; + tableL += 128; + } + else + { + uint32 jL; + for( jL = 0; jL < blocksL; jL++ ) + { + sumL += tableL[ vL & 0x0F ]; + vL >>= 4; + tableL += 16; + } + } + + dataPtrL += 12; + } + + return sumL * ( ptrL->activityFactorE >> 8 ) + ( ( sumL * ( int32 )( ptrL->activityFactorE & 0x0FF ) ) >> 8 ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.h new file mode 100644 index 0000000..6fccc44 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/I04Dns2x4Ftr.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_I04_DNS_2X4_FTR_EM_H +#define bbf_I04_DNS_2X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_I04_DNS_2X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_I04Dns2x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** look up table of weights */ + struct bbs_Int16Arr tableE; + + /** factor to convert activity to proper range (.36) */ + int32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_I04Dns2x4Ftr */ +void bbf_I04Dns2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA ); + +/** resets bbf_I04Dns2x4Ftr */ +void bbf_I04Dns2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_I04Dns2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA, + const struct bbf_I04Dns2x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_I04Dns2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_I04Dns2x4Ftr* ptrA, + const struct bbf_I04Dns2x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_I04Dns2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_I04Dns2x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_I04Dns2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_I04Dns2x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_I04Dns2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_I04Dns2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_I04Dns2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_I04_DNS_2X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.c new file mode 100644 index 0000000..fcbbae7 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/I04Tld2x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Tld2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_I04_TLD_2X4_FTR; + ptrA->baseE.vpActivityE = bbf_I04Tld2x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + bbs_Int16Arr_init( cpA, &ptrA->tableE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Tld2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + bbs_Int16Arr_exit( cpA, &ptrA->tableE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_I04Tld2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA, + const struct bbf_I04Tld2x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + bbs_Int16Arr_copy( cpA, &ptrA->tableE, &srcPtrA->tableE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_I04Tld2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_I04Tld2x4Ftr* ptrA, + const struct bbf_I04Tld2x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( !bbs_Int16Arr_equal( cpA, &ptrA->tableE, &srcPtrA->tableE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Tld2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_I04Tld2x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_Int16Arr_memSize( cpA, &ptrA->tableE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Tld2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_I04Tld2x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_I04Tld2x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_I04_TLD_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->tableE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_I04Tld2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_I04_TLD_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->tableE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_I04Tld2x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_I04Tld2x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_I04Tld2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_I04Tld2x4Ftr* ptrL = ( struct bbf_I04Tld2x4Ftr* )ptrA; + + uint32 iL; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + const int16* tableL = ptrL->tableE.arrPtrE; + const uint32* patchL = patchA; + + int32 sumL = 0; + + for( iL = ptrL->baseE.patchWidthE >> 3; iL > 0; iL-- ) + { + uint32 vL; + + /* compare with pattern */ + uint32 s1L = patchL[ 0 ] ^ dataPtrL[ 0 ]; + uint32 s2L = patchL[ 1 ] ^ dataPtrL[ 1 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL = ( ( s1L + s2L + dataPtrL[ 2 ] ) & 0x88888888 ) >> 3; + + /* compare with pattern */ + s1L = patchL[ 2 ] ^ dataPtrL[ 3 ]; + s2L = patchL[ 3 ] ^ dataPtrL[ 4 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 5 ] ) & 0x88888888 ) >> 2; + + /* compare with pattern */ + s1L = patchL[ 4 ] ^ dataPtrL[ 6 ]; + s2L = patchL[ 5 ] ^ dataPtrL[ 7 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 8 ] ) & 0x88888888 ) >> 1; + + /* compare with pattern */ + s1L = patchL[ 6 ] ^ dataPtrL[ 9 ]; + s2L = patchL[ 7 ] ^ dataPtrL[ 10 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 11 ] ) & 0x88888888 ); + + /* invert bits */ + vL = ~vL; + + /* evaluate vL */ + /* parallel processing of weights (4 weights at a time) */ + sumL += tableL[ ( vL ) & 0x0F ]; + sumL += tableL[ 16 + ( ( vL >> 4 ) & 0x0F ) ]; + sumL += tableL[ 32 + ( ( vL >> 8 ) & 0x0F ) ]; + sumL += tableL[ 48 + ( ( vL >> 12 ) & 0x0F ) ]; + sumL += tableL[ 64 + ( ( vL >> 16 ) & 0x0F ) ]; + sumL += tableL[ 80 + ( ( vL >> 20 ) & 0x0F ) ]; + sumL += tableL[ 96 + ( ( vL >> 24 ) & 0x0F ) ]; + sumL += tableL[ 112 + ( ( vL >> 28 ) & 0x0F ) ]; + + tableL += 128; + dataPtrL += 12; + patchL += 8; + } + + return sumL * ( ptrL->activityFactorE >> 8 ) + ( ( sumL * ( int32 )( ptrL->activityFactorE & 0x0FF ) ) >> 8 ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.h new file mode 100644 index 0000000..db7bc8d --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/I04Tld2x4Ftr.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_I04_TLD_2X4_FTR_EM_H +#define bbf_I04_TLD_2X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_I04_TLD_2X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_I04Tld2x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** look up table of weights */ + struct bbs_Int16Arr tableE; + + /** factor to convert activity to proper range (.36) */ + int32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_I04Tld2x4Ftr */ +void bbf_I04Tld2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA ); + +/** resets bbf_I04Tld2x4Ftr */ +void bbf_I04Tld2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_I04Tld2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA, + const struct bbf_I04Tld2x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_I04Tld2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_I04Tld2x4Ftr* ptrA, + const struct bbf_I04Tld2x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_I04Tld2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_I04Tld2x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_I04Tld2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_I04Tld2x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_I04Tld2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_I04Tld2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_I04Tld2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_I04_TLD_2X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.c new file mode 100644 index 0000000..5198c65 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L01Dns2x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Dns2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L01_DNS_2X4_FTR; + ptrA->baseE.vpActivityE = bbf_L01Dns2x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Dns2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Dns2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA, + const struct bbf_L01Dns2x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L01Dns2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L01Dns2x4Ftr* ptrA, + const struct bbf_L01Dns2x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Dns2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L01Dns2x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Dns2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L01Dns2x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L01Dns2x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L01_DNS_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Dns2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L01_DNS_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L01Dns2x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L01Dns2x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L01Dns2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L01Dns2x4Ftr* ptrL = ( struct bbf_L01Dns2x4Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 1; + uint32 hL = ptrL->baseE.patchHeightE - 3; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + + uint32 iL; + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + /* partial bit sums */ + uint32 bsL = 0; + + uint32 sL[ 8 ]; + uint32 mL[ 4 ]; + + for( iL = 0; iL < wL; iL++ ) + { + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + sL[ 3 ] = ( ( s1L >> 3 ) ^ dataPtrL[ 3 ] ) & borderMaskL; + + sL[ 4 ] = ( ( s2L ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + sL[ 6 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s2L >> 3 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 3 features */ + mL[ 0 ] = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + + ( sL[ 2 ] & 0x11111111 ) + ( sL[ 3 ] & 0x11111111 ) + + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) ); + + mL[ 1 ] = ( ( sL[ 0 ] & 0x22222222 ) + ( sL[ 1 ] & 0x22222222 ) + + ( sL[ 2 ] & 0x22222222 ) + ( sL[ 3 ] & 0x22222222 ) + + ( sL[ 4 ] & 0x22222222 ) + ( sL[ 5 ] & 0x22222222 ) + + ( sL[ 6 ] & 0x22222222 ) + ( sL[ 7 ] & 0x22222222 ) ) >> 1; + + mL[ 2 ] = ( ( sL[ 0 ] & 0x44444444 ) + ( sL[ 1 ] & 0x44444444 ) + + ( sL[ 2 ] & 0x44444444 ) + ( sL[ 3 ] & 0x44444444 ) + + ( sL[ 4 ] & 0x44444444 ) + ( sL[ 5 ] & 0x44444444 ) + + ( sL[ 6 ] & 0x44444444 ) + ( sL[ 7 ] & 0x44444444 ) ) >> 2; + + mL[ 3 ] = ( ( sL[ 0 ] & 0x88888888 ) + ( sL[ 1 ] & 0x88888888 ) + + ( sL[ 2 ] & 0x88888888 ) + ( sL[ 3 ] & 0x88888888 ) + + ( sL[ 4 ] & 0x88888888 ) + ( sL[ 5 ] & 0x88888888 ) + + ( sL[ 6 ] & 0x88888888 ) + ( sL[ 7 ] & 0x88888888 ) ) >> 3; + + /* parallel comparison with thresholds and packing of results into bit array of size patchHeightE - 3 */ + { + uint32 vL = ~dataPtrL[ 8 ]; + vL |= ( ( mL[ 0 ] + dataPtrL[ 9 ] ) & 0x88888888 ) >> 3; + vL |= ( ( mL[ 1 ] + dataPtrL[ 10 ] ) & 0x88888888 ) >> 2; + vL |= ( ( mL[ 2 ] + dataPtrL[ 11 ] ) & 0x88888888 ) >> 1; + vL |= ( ( mL[ 3 ] + dataPtrL[ 12 ] ) & 0x88888888 ); + vL = ( ~vL ) & 0x1FFFFFFF; + + /* compute partial bit sums */ + vL = ( vL & 0x55555555 ) + ( ( vL >> 1 ) & 0x55555555 ); + vL = ( vL & 0x33333333 ) + ( ( vL >> 2 ) & 0x33333333 ); + bsL += ( vL & 0x0F0F0F0F ) + ( ( vL >> 4 ) & 0x0F0F0F0F ); + } + + dataPtrL += 13; + } + + bsL = ( bsL & 0x00FF00FF ) + ( ( bsL >> 8 ) & 0x00FF00FF ); + bsL += bsL >> 16; + + /* compute final activity */ + { + uint32 actL = ( bsL & 0x0FFFF ); + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.h new file mode 100644 index 0000000..6892463 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L01Dns2x4Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L01_DNS_2X4_FTR_EM_H +#define bbf_L01_DNS_2X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L01_DNS_2X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L01Dns2x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L01Dns2x4Ftr */ +void bbf_L01Dns2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA ); + +/** resets bbf_L01Dns2x4Ftr */ +void bbf_L01Dns2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L01Dns2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA, + const struct bbf_L01Dns2x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L01Dns2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L01Dns2x4Ftr* ptrA, + const struct bbf_L01Dns2x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L01Dns2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L01Dns2x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L01Dns2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L01Dns2x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L01Dns2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L01Dns2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L01Dns2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L01_DNS_2X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.c b/Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.c new file mode 100644 index 0000000..896002c --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L01Tld1x1Ftr.h" +#include "b_BitFeatureEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Tld1x1Ftr_init( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L01_TLD_1X1_FTR; + ptrA->baseE.vpActivityE = bbf_L01Tld1x1Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Tld1x1Ftr_exit( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Tld1x1Ftr_copy( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA, + const struct bbf_L01Tld1x1Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L01Tld1x1Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L01Tld1x1Ftr* ptrA, + const struct bbf_L01Tld1x1Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Tld1x1Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L01Tld1x1Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Tld1x1Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L01Tld1x1Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L01Tld1x1Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L01_TLD_1X1_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Tld1x1Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L01_TLD_1X1_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L01Tld1x1Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L01Tld1x1Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L01Tld1x1Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L01Tld1x1Ftr* ptrL = ( struct bbf_L01Tld1x1Ftr* )ptrA; + + int32 iL; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + const uint32* patchL = patchA; + + uint32 bsL = 0; + + for( iL = ptrL->baseE.patchWidthE >> 2; iL > 0; iL-- ) + { + uint32 vL; + vL = ( patchL[ 0 ] ^ dataPtrL[ 0 ] ) & dataPtrL[ 1 ]; + bsL += bbf_BIT_SUM_32( vL ); + + vL = ( patchL[ 1 ] ^ dataPtrL[ 2 ] ) & dataPtrL[ 3 ]; + bsL += bbf_BIT_SUM_32( vL ); + + vL = ( patchL[ 2 ] ^ dataPtrL[ 4 ] ) & dataPtrL[ 5 ]; + bsL += bbf_BIT_SUM_32( vL ); + + vL = ( patchL[ 3 ] ^ dataPtrL[ 6 ] ) & dataPtrL[ 7 ]; + bsL += bbf_BIT_SUM_32( vL ); + + dataPtrL += 8; + patchL += 4; + } + + return bsL * ptrL->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.h b/Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.h new file mode 100644 index 0000000..6f59a7c --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L01Tld1x1Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L01_TLD_1X1_FTR_EM_H +#define bbf_L01_TLD_1X1_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L01_TLD_1X1_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L01Tld1x1Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L01Tld1x1Ftr */ +void bbf_L01Tld1x1Ftr_init( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA ); + +/** resets bbf_L01Tld1x1Ftr */ +void bbf_L01Tld1x1Ftr_exit( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L01Tld1x1Ftr_copy( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA, + const struct bbf_L01Tld1x1Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L01Tld1x1Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L01Tld1x1Ftr* ptrA, + const struct bbf_L01Tld1x1Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L01Tld1x1Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L01Tld1x1Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L01Tld1x1Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L01Tld1x1Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L01Tld1x1Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L01Tld1x1Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L01Tld1x1Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L01_TLD_1X1_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.c new file mode 100644 index 0000000..62758c1 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L01Tld2x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Tld2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L01_TLD_2X4_FTR; + ptrA->baseE.vpActivityE = bbf_L01Tld2x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Tld2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L01Tld2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA, + const struct bbf_L01Tld2x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L01Tld2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L01Tld2x4Ftr* ptrA, + const struct bbf_L01Tld2x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Tld2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L01Tld2x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Tld2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L01Tld2x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L01Tld2x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L01_TLD_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L01Tld2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L01_TLD_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L01Tld2x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L01Tld2x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L01Tld2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L01Tld2x4Ftr* ptrL = ( struct bbf_L01Tld2x4Ftr* )ptrA; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + const uint32* patchL = patchA; + + uint32 iL; + + uint32 bs1L = 0; + uint32 bs2L = 0; + + for( iL = ptrL->baseE.patchWidthE >> 3; iL > 0; iL-- ) + { + uint32 vL = ~dataPtrL[ 0 ]; + + /* compare with pattern */ + uint32 s1L = patchL[ 0 ] ^ dataPtrL[ 1 ]; + uint32 s2L = patchL[ 1 ] ^ dataPtrL[ 2 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 3 ] ) & 0x88888888 ) >> 3; + + /* compare with pattern */ + s1L = patchL[ 2 ] ^ dataPtrL[ 4 ]; + s2L = patchL[ 3 ] ^ dataPtrL[ 5 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 6 ] ) & 0x88888888 ) >> 2; + + /* compare with pattern */ + s1L = patchL[ 4 ] ^ dataPtrL[ 7 ]; + s2L = patchL[ 5 ] ^ dataPtrL[ 8 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 9 ] ) & 0x88888888 ) >> 1; + + /* compare with pattern */ + s1L = patchL[ 6 ] ^ dataPtrL[ 10 ]; + s2L = patchL[ 7 ] ^ dataPtrL[ 11 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 12 ] ) & 0x88888888 ); + + vL = ~vL; + + /* add bits */ + bs1L += vL & 0x55555555; + bs2L += ( vL >> 1 ) & 0x55555555; + + dataPtrL += 13; + patchL += 8; + } + + /* complete partial sums and compute final confidence */ + bs1L = ( bs1L & 0x33333333 ) + ( ( bs1L >> 2 ) & 0x33333333 ) + ( bs2L & 0x33333333 ) + ( ( bs2L >> 2 ) & 0x33333333 ); + bs1L = ( bs1L & 0x0F0F0F0F ) + ( ( bs1L >> 4 ) & 0x0F0F0F0F ); + bs1L += bs1L >> 8; + + /* compute final activity */ + { + uint32 actL = ( bs1L + ( bs1L >> 16 ) ) & 0x0FF; + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.h new file mode 100644 index 0000000..5f33eb2 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L01Tld2x4Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L01_TLD_2X4_FTR_EM_H +#define bbf_L01_TLD_2X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L01_TLD_2X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L01Tld2x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L01Tld2x4Ftr */ +void bbf_L01Tld2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA ); + +/** resets bbf_L01Tld2x4Ftr */ +void bbf_L01Tld2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L01Tld2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA, + const struct bbf_L01Tld2x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L01Tld2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L01Tld2x4Ftr* ptrA, + const struct bbf_L01Tld2x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L01Tld2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L01Tld2x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L01Tld2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L01Tld2x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L01Tld2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L01Tld2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L01Tld2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L01_TLD_2X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.c b/Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.c new file mode 100644 index 0000000..c06ccd4 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L04Dns2x2Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns2x2Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L04_DNS_2X2_FTR; + ptrA->baseE.vpActivityE = bbf_L04Dns2x2Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->wShiftE = 0; + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns2x2Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->wShiftE = 0; + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns2x2Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA, + const struct bbf_L04Dns2x2Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->wShiftE = srcPtrA->wShiftE; + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L04Dns2x2Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Dns2x2Ftr* ptrA, + const struct bbf_L04Dns2x2Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->wShiftE != srcPtrA->wShiftE ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns2x2Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Dns2x2Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->wShiftE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns2x2Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Dns2x2Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L04Dns2x2Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L04_DNS_2X2_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->wShiftE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns2x2Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L04_DNS_2X2_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->wShiftE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L04Dns2x2Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L04Dns2x2Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L04Dns2x2Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L04Dns2x2Ftr* ptrL = ( struct bbf_L04Dns2x2Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 1; + uint32 hL = ptrL->baseE.patchHeightE - 1; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + uint32 iL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + const uint32* patchL = patchA; + int32 sumL = 0; + + uint32 bL[ 4 ] = { 0, 0, 0, 0 }; /* bit sum */ + + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL = ( patchL[ 0 ] ^ dataPtrL[ 0 ] ) & + ( ( patchL[ 0 ] >> 1 ) ^ dataPtrL[ 1 ] ) & + ( ( patchL[ 1 ] ) ^ dataPtrL[ 2 ] ) & + ( ( patchL[ 1 ] >> 1 ) ^ dataPtrL[ 3 ] ) & borderMaskL; + + + { + uint32 vmL; + vmL = vL & dataPtrL[ 4 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 5 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL); + vmL = vL & dataPtrL[ 6 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 7 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + } + + sumL += bbf_BIT_SUM_32( vL ); + + patchL++; + dataPtrL += 8; + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 3 ) + ( bL[ 1 ] << 2 ) + ( bL[ 2 ] << 1 ) + bL[ 3 ] ); + return actL * ptrL->activityFactorE + sumL * ptrL->wShiftE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.h b/Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.h new file mode 100644 index 0000000..339be50 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Dns2x2Ftr.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L04_DNS_2X2_FTR_EM_H +#define bbf_L04_DNS_2X2_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L04_DNS_2X2_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L04Dns2x2Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** weight shift */ + int32 wShiftE; + + /** factor to convert activity to proper range */ + int32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L04Dns2x2Ftr */ +void bbf_L04Dns2x2Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA ); + +/** resets bbf_L04Dns2x2Ftr */ +void bbf_L04Dns2x2Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L04Dns2x2Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA, + const struct bbf_L04Dns2x2Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L04Dns2x2Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Dns2x2Ftr* ptrA, + const struct bbf_L04Dns2x2Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L04Dns2x2Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Dns2x2Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L04Dns2x2Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Dns2x2Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L04Dns2x2Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Dns2x2Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L04Dns2x2Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L04_DNS_2X2_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.c new file mode 100644 index 0000000..87e3e2d --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L04Dns2x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L04_DNS_2X4_FTR; + ptrA->baseE.vpActivityE = bbf_L04Dns2x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA, + const struct bbf_L04Dns2x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L04Dns2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Dns2x4Ftr* ptrA, + const struct bbf_L04Dns2x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Dns2x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Dns2x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L04Dns2x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L04_DNS_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L04_DNS_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L04Dns2x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L04Dns2x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L04Dns2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L04Dns2x4Ftr* ptrL = ( struct bbf_L04Dns2x4Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 1; + uint32 hL = ptrL->baseE.patchHeightE - 3; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + + uint32 iL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + uint32 sL[ 8 ]; + uint32 mL[ 4 ]; + uint32 bL[ 4 ] = { 0, 0, 0, 0 }; /* bit sum */ + + for( iL = 0; iL < wL; iL++ ) + { + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + sL[ 3 ] = ( ( s1L >> 3 ) ^ dataPtrL[ 3 ] ) & borderMaskL; + + sL[ 4 ] = ( ( s2L ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + sL[ 6 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s2L >> 3 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 3 features */ + mL[ 0 ] = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + + ( sL[ 2 ] & 0x11111111 ) + ( sL[ 3 ] & 0x11111111 ) + + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) ); + + mL[ 1 ] = ( ( sL[ 0 ] & 0x22222222 ) + ( sL[ 1 ] & 0x22222222 ) + + ( sL[ 2 ] & 0x22222222 ) + ( sL[ 3 ] & 0x22222222 ) + + ( sL[ 4 ] & 0x22222222 ) + ( sL[ 5 ] & 0x22222222 ) + + ( sL[ 6 ] & 0x22222222 ) + ( sL[ 7 ] & 0x22222222 ) ) >> 1; + + mL[ 2 ] = ( ( sL[ 0 ] & 0x44444444 ) + ( sL[ 1 ] & 0x44444444 ) + + ( sL[ 2 ] & 0x44444444 ) + ( sL[ 3 ] & 0x44444444 ) + + ( sL[ 4 ] & 0x44444444 ) + ( sL[ 5 ] & 0x44444444 ) + + ( sL[ 6 ] & 0x44444444 ) + ( sL[ 7 ] & 0x44444444 ) ) >> 2; + + mL[ 3 ] = ( ( sL[ 0 ] & 0x88888888 ) + ( sL[ 1 ] & 0x88888888 ) + + ( sL[ 2 ] & 0x88888888 ) + ( sL[ 3 ] & 0x88888888 ) + + ( sL[ 4 ] & 0x88888888 ) + ( sL[ 5 ] & 0x88888888 ) + + ( sL[ 6 ] & 0x88888888 ) + ( sL[ 7 ] & 0x88888888 ) ) >> 3; + + /* parallel comparison with thresholds and packing of results into bit array of size patchHeightE - 3 */ + { + uint32 vL = 0; + vL |= ( ( mL[ 0 ] + dataPtrL[ 8 ] ) & 0x88888888 ) >> 3; + vL |= ( ( mL[ 1 ] + dataPtrL[ 9 ] ) & 0x88888888 ) >> 2; + vL |= ( ( mL[ 2 ] + dataPtrL[ 10 ] ) & 0x88888888 ) >> 1; + vL |= ( ( mL[ 3 ] + dataPtrL[ 11 ] ) & 0x88888888 ); + + vL = ( ~vL ) & 0x1FFFFFFF; + + /* mask out and count bits */ + { + uint32 vmL; + vmL = vL & dataPtrL[ 12 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 13 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL); + vmL = vL & dataPtrL[ 14 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 15 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + } + + dataPtrL += 16; + } + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 3 ) + ( bL[ 1 ] << 2 ) + ( bL[ 2 ] << 1 ) + bL[ 3 ] ); + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.h new file mode 100644 index 0000000..bf210e7 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Dns2x4Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L04_DNS_2X4_FTR_EM_H +#define bbf_L04_DNS_2X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L04_DNS_2X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L04Dns2x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L04Dns2x4Ftr */ +void bbf_L04Dns2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA ); + +/** resets bbf_L04Dns2x4Ftr */ +void bbf_L04Dns2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L04Dns2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA, + const struct bbf_L04Dns2x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L04Dns2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Dns2x4Ftr* ptrA, + const struct bbf_L04Dns2x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L04Dns2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Dns2x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L04Dns2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Dns2x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L04Dns2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Dns2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L04Dns2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L04_DNS_2X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.c b/Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.c new file mode 100644 index 0000000..edb5553 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L04Dns3x3Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns3x3Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L04_DNS_3X3_FTR; + ptrA->baseE.vpActivityE = bbf_L04Dns3x3Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns3x3Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Dns3x3Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA, + const struct bbf_L04Dns3x3Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L04Dns3x3Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Dns3x3Ftr* ptrA, + const struct bbf_L04Dns3x3Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns3x3Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Dns3x3Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns3x3Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Dns3x3Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L04Dns3x3Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L04_DNS_3X3_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Dns3x3Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L04_DNS_3X3_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L04Dns3x3Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L04Dns3x3Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L04Dns3x3Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L04Dns3x3Ftr* ptrL = ( struct bbf_L04Dns3x3Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 2; + uint32 hL = ptrL->baseE.patchHeightE - 2; + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + uint32 iL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + uint32 sL[ 9 ]; + uint32 bL[ 4 ] = { 0, 0, 0, 0 }; /* bit sum */ + + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL, mL, tL; /* bit sum and thresholds */ + + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + uint32 s3L = patchA[ iL + 2 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + + sL[ 3 ] = ( ( s2L ) ^ dataPtrL[ 3 ] ) & borderMaskL; + sL[ 4 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + + sL[ 6 ] = ( ( s3L ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s3L >> 1 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + sL[ 8 ] = ( ( s3L >> 2 ) ^ dataPtrL[ 8 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 2 features */ + vL = 0; + + mL = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + ( sL[ 2 ] & 0x11111111 ) + + ( sL[ 3 ] & 0x11111111 ) + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) + ( sL[ 8 ] & 0x11111111 ) ); + + tL = dataPtrL[ 9 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 4; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ); + + /* shift values to prevent overflow in next summation */ + sL[ 0 ] >>= 1; sL[ 1 ] >>= 1; sL[ 2 ] >>= 1; + sL[ 3 ] >>= 1; sL[ 4 ] >>= 1; sL[ 5 ] >>= 1; + sL[ 6 ] >>= 1; sL[ 7 ] >>= 1; sL[ 8 ] >>= 1; + + mL = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + ( sL[ 2 ] & 0x11111111 ) + + ( sL[ 3 ] & 0x11111111 ) + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) + ( sL[ 8 ] & 0x11111111 ) ); + + tL = dataPtrL[ 10 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 3; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ) << 1; + + mL = ( ( sL[ 0 ] & 0x02222222 ) + ( sL[ 1 ] & 0x02222222 ) + ( sL[ 2 ] & 0x02222222 ) + + ( sL[ 3 ] & 0x02222222 ) + ( sL[ 4 ] & 0x02222222 ) + ( sL[ 5 ] & 0x02222222 ) + + ( sL[ 6 ] & 0x02222222 ) + ( sL[ 7 ] & 0x02222222 ) + ( sL[ 8 ] & 0x02222222 ) ) >> 1; + + tL = dataPtrL[ 11 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 2; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ) << 2; + + mL = ( ( sL[ 0 ] & 0x04444444 ) + ( sL[ 1 ] & 0x04444444 ) + ( sL[ 2 ] & 0x04444444 ) + + ( sL[ 3 ] & 0x04444444 ) + ( sL[ 4 ] & 0x04444444 ) + ( sL[ 5 ] & 0x04444444 ) + + ( sL[ 6 ] & 0x04444444 ) + ( sL[ 7 ] & 0x04444444 ) + ( sL[ 8 ] & 0x04444444 ) ) >> 2; + + tL = dataPtrL[ 12 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 1; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ) << 3; + + vL = ~vL; + + /* mask out and count bits */ + { + uint32 vmL; + vmL = vL & dataPtrL[ 13 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 14 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL); + vmL = vL & dataPtrL[ 15 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 16 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + } + + dataPtrL += 17; + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 3 ) + ( bL[ 1 ] << 2 ) + ( bL[ 2 ] << 1 ) + bL[ 3 ] ); + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.h b/Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.h new file mode 100644 index 0000000..cfc691b --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Dns3x3Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L04_DNS_3X3_FTR_EM_H +#define bbf_L04_DNS_3X3_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L04_DNS_3X3_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L04Dns3x3Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L04Dns3x3Ftr */ +void bbf_L04Dns3x3Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA ); + +/** resets bbf_L04Dns3x3Ftr */ +void bbf_L04Dns3x3Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L04Dns3x3Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA, + const struct bbf_L04Dns3x3Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L04Dns3x3Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Dns3x3Ftr* ptrA, + const struct bbf_L04Dns3x3Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L04Dns3x3Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Dns3x3Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L04Dns3x3Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Dns3x3Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L04Dns3x3Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Dns3x3Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L04Dns3x3Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L04_DNS_3X3_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.c new file mode 100644 index 0000000..2eeec73 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L04Tld2x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Tld2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L04_TLD_2X4_FTR; + ptrA->baseE.vpActivityE = bbf_L04Tld2x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Tld2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L04Tld2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA, + const struct bbf_L04Tld2x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L04Tld2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Tld2x4Ftr* ptrA, + const struct bbf_L04Tld2x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Tld2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Tld2x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Tld2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Tld2x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L04Tld2x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L04_TLD_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L04Tld2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L04_TLD_2X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L04Tld2x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L04Tld2x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L04Tld2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L04Tld2x4Ftr* ptrL = ( struct bbf_L04Tld2x4Ftr* )ptrA; + + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + const uint32* patchL = patchA; + + uint32 iL; + + uint32 bL[ 4 ] = { 0, 0, 0, 0 }; /* bit sum */ + + for( iL = ptrL->baseE.patchWidthE >> 3; iL > 0; iL-- ) + { + uint32 vL; + + /* compare with pattern */ + uint32 s1L = patchL[ 0 ] ^ dataPtrL[ 0 ]; + uint32 s2L = patchL[ 1 ] ^ dataPtrL[ 1 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL = ( ( s1L + s2L + dataPtrL[ 2 ] ) & 0x88888888 ) >> 3; + + /* compare with pattern */ + s1L = patchL[ 2 ] ^ dataPtrL[ 3 ]; + s2L = patchL[ 3 ] ^ dataPtrL[ 4 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 5 ] ) & 0x88888888 ) >> 2; + + /* compare with pattern */ + s1L = patchL[ 4 ] ^ dataPtrL[ 6 ]; + s2L = patchL[ 5 ] ^ dataPtrL[ 7 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 8 ] ) & 0x88888888 ) >> 1; + + /* compare with pattern */ + s1L = patchL[ 6 ] ^ dataPtrL[ 9 ]; + s2L = patchL[ 7 ] ^ dataPtrL[ 10 ]; + + /* bit count */ + s1L = ( s1L & 0x55555555 ) + ( ( s1L >> 1 ) & 0x55555555 ); + s1L = ( s1L & 0x33333333 ) + ( ( s1L >> 2 ) & 0x33333333 ); + s2L = ( s2L & 0x55555555 ) + ( ( s2L >> 1 ) & 0x55555555 ); + s2L = ( s2L & 0x33333333 ) + ( ( s2L >> 2 ) & 0x33333333 ); + + /* compare with threshold and store results in vL */ + vL |= ( ( s1L + s2L + dataPtrL[ 11 ] ) & 0x88888888 ); + + /* invert bits */ + vL = ~vL; + + { + uint32 vmL; + vmL = vL & dataPtrL[ 12 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 13 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL); + vmL = vL & dataPtrL[ 14 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 15 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + } + + dataPtrL += 16; + patchL += 8; + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 3 ) + ( bL[ 1 ] << 2 ) + ( bL[ 2 ] << 1 ) + bL[ 3 ] ); + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.h new file mode 100644 index 0000000..4033753 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L04Tld2x4Ftr.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L04_TLD_2X4_FTR_EM_H +#define bbf_L04_TLD_2X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L04_TLD_2X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L04Tld2x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range (.36) */ + int32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L04Tld2x4Ftr */ +void bbf_L04Tld2x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA ); + +/** resets bbf_L04Tld2x4Ftr */ +void bbf_L04Tld2x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L04Tld2x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA, + const struct bbf_L04Tld2x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L04Tld2x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L04Tld2x4Ftr* ptrA, + const struct bbf_L04Tld2x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L04Tld2x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L04Tld2x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L04Tld2x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L04Tld2x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L04Tld2x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L04Tld2x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L04Tld2x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L04_TLD_2X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.c b/Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.c new file mode 100644 index 0000000..438c8ac --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L06Dns3x3Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L06Dns3x3Ftr_init( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L06_DNS_3X3_FTR; + ptrA->baseE.vpActivityE = bbf_L06Dns3x3Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L06Dns3x3Ftr_exit( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L06Dns3x3Ftr_copy( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA, + const struct bbf_L06Dns3x3Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L06Dns3x3Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L06Dns3x3Ftr* ptrA, + const struct bbf_L06Dns3x3Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06Dns3x3Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L06Dns3x3Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06Dns3x3Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L06Dns3x3Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L06Dns3x3Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L06_DNS_3X3_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06Dns3x3Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L06_DNS_3X3_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L06Dns3x3Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L06Dns3x3Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L06Dns3x3Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L06Dns3x3Ftr* ptrL = ( struct bbf_L06Dns3x3Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 2; + uint32 hL = ptrL->baseE.patchHeightE - 2; + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + uint32 iL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + uint32 sL[ 9 ]; + uint32 bL[ 6 ] = { 0, 0, 0, 0, 0, 0 }; /* bit sum */ + + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL, mL, tL; /* bit sum and thresholds */ + + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + uint32 s3L = patchA[ iL + 2 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + + sL[ 3 ] = ( ( s2L ) ^ dataPtrL[ 3 ] ) & borderMaskL; + sL[ 4 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + + sL[ 6 ] = ( ( s3L ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s3L >> 1 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + sL[ 8 ] = ( ( s3L >> 2 ) ^ dataPtrL[ 8 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 2 features */ + + vL = 0; + + mL = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + ( sL[ 2 ] & 0x11111111 ) + + ( sL[ 3 ] & 0x11111111 ) + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) + ( sL[ 8 ] & 0x11111111 ) ); + + tL = dataPtrL[ 9 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 4; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ); + + /* shift values to prevent overflow in next summation */ + sL[ 0 ] >>= 1; sL[ 1 ] >>= 1; sL[ 2 ] >>= 1; + sL[ 3 ] >>= 1; sL[ 4 ] >>= 1; sL[ 5 ] >>= 1; + sL[ 6 ] >>= 1; sL[ 7 ] >>= 1; sL[ 8 ] >>= 1; + + mL = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + ( sL[ 2 ] & 0x11111111 ) + + ( sL[ 3 ] & 0x11111111 ) + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) + ( sL[ 8 ] & 0x11111111 ) ); + + tL = dataPtrL[ 10 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 3; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ) << 1; + + mL = ( ( sL[ 0 ] & 0x02222222 ) + ( sL[ 1 ] & 0x02222222 ) + ( sL[ 2 ] & 0x02222222 ) + + ( sL[ 3 ] & 0x02222222 ) + ( sL[ 4 ] & 0x02222222 ) + ( sL[ 5 ] & 0x02222222 ) + + ( sL[ 6 ] & 0x02222222 ) + ( sL[ 7 ] & 0x02222222 ) + ( sL[ 8 ] & 0x02222222 ) ) >> 1; + + tL = dataPtrL[ 11 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 2; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ) << 2; + + mL = ( ( sL[ 0 ] & 0x04444444 ) + ( sL[ 1 ] & 0x04444444 ) + ( sL[ 2 ] & 0x04444444 ) + + ( sL[ 3 ] & 0x04444444 ) + ( sL[ 4 ] & 0x04444444 ) + ( sL[ 5 ] & 0x04444444 ) + + ( sL[ 6 ] & 0x04444444 ) + ( sL[ 7 ] & 0x04444444 ) + ( sL[ 8 ] & 0x04444444 ) ) >> 2; + + tL = dataPtrL[ 12 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) ) & 0x10101010 ) >> 1; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) ) & 0x10101010 ) << 3; + + vL = ~vL; + + /* mask out and count bits */ + { + uint32 vmL; + vmL = vL & dataPtrL[ 13 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 14 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 15 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 16 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 17 ]; + bL[ 4 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 18 ]; + bL[ 5 ] += bbf_BIT_SUM_32( vmL ); + } + + dataPtrL += 19; + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 5 ) + ( bL[ 1 ] << 4 ) + ( bL[ 2 ] << 3 ) + + ( bL[ 3 ] << 2 ) + ( bL[ 4 ] << 1 ) + ( bL[ 5 ] ) ); + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.h b/Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.h new file mode 100644 index 0000000..bd4ace4 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L06Dns3x3Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L06_DNS_3X3_FTR_EM_H +#define bbf_L06_DNS_3X3_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L06_DNS_3X3_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L06Dns3x3Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L06Dns3x3Ftr */ +void bbf_L06Dns3x3Ftr_init( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA ); + +/** resets bbf_L06Dns3x3Ftr */ +void bbf_L06Dns3x3Ftr_exit( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L06Dns3x3Ftr_copy( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA, + const struct bbf_L06Dns3x3Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L06Dns3x3Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L06Dns3x3Ftr* ptrA, + const struct bbf_L06Dns3x3Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L06Dns3x3Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L06Dns3x3Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L06Dns3x3Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L06Dns3x3Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L06Dns3x3Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L06Dns3x3Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L06Dns3x3Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L06_DNS_3X3_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.c new file mode 100644 index 0000000..bb33edc --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.c @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L06Dns4x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L06Dns4x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L06_DNS_4X4_FTR; + ptrA->baseE.vpActivityE = bbf_L06Dns4x4Ftr_activity; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L06Dns4x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L06Dns4x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA, + const struct bbf_L06Dns4x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L06Dns4x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L06Dns4x4Ftr* ptrA, + const struct bbf_L06Dns4x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06Dns4x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L06Dns4x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06Dns4x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L06Dns4x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L06Dns4x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L06_DNS_4X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06Dns4x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L06_DNS_4X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L06Dns4x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L06Dns4x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L06Dns4x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L06Dns4x4Ftr* ptrL = ( struct bbf_L06Dns4x4Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 3; + uint32 hL = ptrL->baseE.patchHeightE - 3; + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + uint32 iL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + uint32 sL[ 16 ]; + uint32 bL[ 6 ] = { 0, 0, 0, 0, 0, 0 }; /* bit sum */ + + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL, mL, tL; /* bit sum and thresholds */ + + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + uint32 s3L = patchA[ iL + 2 ]; + uint32 s4L = patchA[ iL + 3 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + sL[ 3 ] = ( ( s1L >> 3 ) ^ dataPtrL[ 3 ] ) & borderMaskL; + + sL[ 4 ] = ( ( s2L ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + sL[ 6 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s2L >> 3 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + + sL[ 8 ] = ( ( s3L ) ^ dataPtrL[ 8 ] ) & borderMaskL; + sL[ 9 ] = ( ( s3L >> 1 ) ^ dataPtrL[ 9 ] ) & borderMaskL; + sL[ 10 ] = ( ( s3L >> 2 ) ^ dataPtrL[ 10 ] ) & borderMaskL; + sL[ 11 ] = ( ( s3L >> 3 ) ^ dataPtrL[ 11 ] ) & borderMaskL; + + sL[ 12 ] = ( ( s4L ) ^ dataPtrL[ 12 ] ) & borderMaskL; + sL[ 13 ] = ( ( s4L >> 1 ) ^ dataPtrL[ 13 ] ) & borderMaskL; + sL[ 14 ] = ( ( s4L >> 2 ) ^ dataPtrL[ 14 ] ) & borderMaskL; + sL[ 15 ] = ( ( s4L >> 3 ) ^ dataPtrL[ 15 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 2 features */ + + vL = 0; + + mL = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + ( sL[ 2 ] & 0x11111111 ) + + ( sL[ 3 ] & 0x11111111 ) + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) + ( sL[ 8 ] & 0x11111111 ) + + ( sL[ 9 ] & 0x11111111 ) + ( sL[ 10 ] & 0x11111111 ) + ( sL[ 11 ] & 0x11111111 ) + + ( sL[ 12 ] & 0x11111111 ) + ( sL[ 13 ] & 0x11111111 ) + ( sL[ 14 ] & 0x11111111 ) ); + + tL = dataPtrL[ 16 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 4; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ); + + mL = ( ( sL[ 0 ] & 0x02222222 ) + ( sL[ 1 ] & 0x02222222 ) + ( sL[ 2 ] & 0x02222222 ) + + ( sL[ 3 ] & 0x02222222 ) + ( sL[ 4 ] & 0x02222222 ) + ( sL[ 5 ] & 0x02222222 ) + + ( sL[ 6 ] & 0x02222222 ) + ( sL[ 7 ] & 0x02222222 ) + ( sL[ 8 ] & 0x02222222 ) + + ( sL[ 9 ] & 0x02222222 ) + ( sL[ 10 ] & 0x02222222 ) + ( sL[ 11 ] & 0x02222222 ) + + ( sL[ 12 ] & 0x02222222 ) + ( sL[ 13 ] & 0x02222222 ) + ( sL[ 14 ] & 0x02222222 ) ) >> 1; + + sL[ 15 ] >>= 1; + tL = dataPtrL[ 17 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 3; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ) << 1; + + mL = ( ( sL[ 0 ] & 0x04444444 ) + ( sL[ 1 ] & 0x04444444 ) + ( sL[ 2 ] & 0x04444444 ) + + ( sL[ 3 ] & 0x04444444 ) + ( sL[ 4 ] & 0x04444444 ) + ( sL[ 5 ] & 0x04444444 ) + + ( sL[ 6 ] & 0x04444444 ) + ( sL[ 7 ] & 0x04444444 ) + ( sL[ 8 ] & 0x04444444 ) + + ( sL[ 9 ] & 0x04444444 ) + ( sL[ 10 ] & 0x04444444 ) + ( sL[ 11 ] & 0x04444444 ) + + ( sL[ 12 ] & 0x04444444 ) + ( sL[ 13 ] & 0x04444444 ) + ( sL[ 14 ] & 0x04444444 ) ) >> 2; + + sL[ 15 ] >>= 1; + tL = dataPtrL[ 18 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 2; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ) << 2; + + mL = ( ( sL[ 0 ] & 0x08888888 ) + ( sL[ 1 ] & 0x08888888 ) + ( sL[ 2 ] & 0x08888888 ) + + ( sL[ 3 ] & 0x08888888 ) + ( sL[ 4 ] & 0x08888888 ) + ( sL[ 5 ] & 0x08888888 ) + + ( sL[ 6 ] & 0x08888888 ) + ( sL[ 7 ] & 0x08888888 ) + ( sL[ 8 ] & 0x08888888 ) + + ( sL[ 9 ] & 0x08888888 ) + ( sL[ 10 ] & 0x08888888 ) + ( sL[ 11 ] & 0x08888888 ) + + ( sL[ 12 ] & 0x08888888 ) + ( sL[ 13 ] & 0x08888888 ) + ( sL[ 14 ] & 0x08888888 ) ) >> 3; + + sL[ 15 ] >>= 1; + tL = dataPtrL[ 19 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 1; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ) << 3; + + vL = ~vL; + + /* mask out and count bits */ + { + uint32 vmL; + vmL = vL & dataPtrL[ 20 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 21 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL); + vmL = vL & dataPtrL[ 22 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 23 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 24 ]; + bL[ 4 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 25 ]; + bL[ 5 ] += bbf_BIT_SUM_32( vmL ); + } + + dataPtrL += 26; + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 5 ) + ( bL[ 1 ] << 4 ) + ( bL[ 2 ] << 3 ) + + ( bL[ 3 ] << 2 ) + ( bL[ 4 ] << 1 ) + ( bL[ 5 ] ) ); + + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.h new file mode 100644 index 0000000..4085dd5 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L06Dns4x4Ftr.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L06_DNS_4X4_FTR_EM_H +#define bbf_L06_DNS_4X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L06_DNS_4X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L06Dns4x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L06Dns4x4Ftr */ +void bbf_L06Dns4x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA ); + +/** resets bbf_L06Dns4x4Ftr */ +void bbf_L06Dns4x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L06Dns4x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA, + const struct bbf_L06Dns4x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L06Dns4x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L06Dns4x4Ftr* ptrA, + const struct bbf_L06Dns4x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L06Dns4x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L06Dns4x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L06Dns4x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L06Dns4x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L06Dns4x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L06Dns4x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L06Dns4x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L06_DNS_4X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.c b/Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.c new file mode 100644 index 0000000..0077ee2 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.c @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/L06DnsNx4x4Ftr.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L06DnsNx4x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA ) +{ + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_L06_DNS_NX4X4_FTR; + ptrA->baseE.vpActivityE = bbf_L06DnsNx4x4Ftr_activity; + ptrA->layersE = 0; + bbs_UInt32Arr_init( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_L06DnsNx4x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA ) +{ + bbf_Feature_exit( cpA, &ptrA->baseE ); + ptrA->layersE = 0; + bbs_UInt32Arr_exit( cpA, &ptrA->dataArrE ); + ptrA->activityFactorE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_L06DnsNx4x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA, + const struct bbf_L06DnsNx4x4Ftr* srcPtrA ) +{ + bbf_Feature_copy( cpA, &ptrA->baseE, &srcPtrA->baseE ); + ptrA->layersE = srcPtrA->layersE; + bbs_UInt32Arr_copy( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ); + ptrA->activityFactorE = srcPtrA->activityFactorE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_L06DnsNx4x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L06DnsNx4x4Ftr* ptrA, + const struct bbf_L06DnsNx4x4Ftr* srcPtrA ) +{ + if( !bbf_Feature_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE; + if( ptrA->layersE != srcPtrA->layersE ) return FALSE; + if( !bbs_UInt32Arr_equal( cpA, &ptrA->dataArrE, &srcPtrA->dataArrE ) ) return FALSE; + if( ptrA->activityFactorE != srcPtrA->activityFactorE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06DnsNx4x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L06DnsNx4x4Ftr* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_SIZEOF16( ptrA->layersE ); + memSizeL += bbs_UInt32Arr_memSize( cpA, &ptrA->dataArrE ); + memSizeL += bbs_SIZEOF16( ptrA->activityFactorE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06DnsNx4x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L06DnsNx4x4Ftr* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_L06DnsNx4x4Ftr_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_L06_DNS_NX4X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->layersE, memPtrA ); + memPtrA += bbs_UInt32Arr_memWrite( cpA, &ptrA->dataArrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->activityFactorE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_L06DnsNx4x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_L06_DNS_NX4X4_FTR_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->layersE, memPtrA ); + memPtrA += bbs_UInt32Arr_memRead( cpA, &ptrA->dataArrE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->activityFactorE, memPtrA ); + if( memSizeL != bbf_L06DnsNx4x4Ftr_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_L06DnsNx4x4Ftr_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_L06DnsNx4x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_L06DnsNx4x4Ftr* ptrL = ( struct bbf_L06DnsNx4x4Ftr* )ptrA; + + uint32 wL = ptrL->baseE.patchWidthE - 3; + uint32 hL = ptrL->baseE.patchHeightE - 3; + const uint32* dataPtrL = ptrL->dataArrE.arrPtrE; + uint32 iL, jL; + + uint32 borderMaskL = ( ( uint32 )1 << hL ) - 1; + + uint32 sL[ 16 ]; + uint32 bL[ 6 ] = { 0, 0, 0, 0, 0, 0 }; /* bit sum */ + + for( jL = 0 ; jL < ptrL->layersE; jL++ ) + { + for( iL = 0; iL < wL; iL++ ) + { + uint32 vL, mL, tL; /* bit sum and thresholds */ + + uint32 s1L = patchA[ iL ]; + uint32 s2L = patchA[ iL + 1 ]; + uint32 s3L = patchA[ iL + 2 ]; + uint32 s4L = patchA[ iL + 3 ]; + + /* comparison of pixels with patchHeightE - 3 features */ + sL[ 0 ] = ( ( s1L ) ^ dataPtrL[ 0 ] ) & borderMaskL; + sL[ 1 ] = ( ( s1L >> 1 ) ^ dataPtrL[ 1 ] ) & borderMaskL; + sL[ 2 ] = ( ( s1L >> 2 ) ^ dataPtrL[ 2 ] ) & borderMaskL; + sL[ 3 ] = ( ( s1L >> 3 ) ^ dataPtrL[ 3 ] ) & borderMaskL; + + sL[ 4 ] = ( ( s2L ) ^ dataPtrL[ 4 ] ) & borderMaskL; + sL[ 5 ] = ( ( s2L >> 1 ) ^ dataPtrL[ 5 ] ) & borderMaskL; + sL[ 6 ] = ( ( s2L >> 2 ) ^ dataPtrL[ 6 ] ) & borderMaskL; + sL[ 7 ] = ( ( s2L >> 3 ) ^ dataPtrL[ 7 ] ) & borderMaskL; + + sL[ 8 ] = ( ( s3L ) ^ dataPtrL[ 8 ] ) & borderMaskL; + sL[ 9 ] = ( ( s3L >> 1 ) ^ dataPtrL[ 9 ] ) & borderMaskL; + sL[ 10 ] = ( ( s3L >> 2 ) ^ dataPtrL[ 10 ] ) & borderMaskL; + sL[ 11 ] = ( ( s3L >> 3 ) ^ dataPtrL[ 11 ] ) & borderMaskL; + + sL[ 12 ] = ( ( s4L ) ^ dataPtrL[ 12 ] ) & borderMaskL; + sL[ 13 ] = ( ( s4L >> 1 ) ^ dataPtrL[ 13 ] ) & borderMaskL; + sL[ 14 ] = ( ( s4L >> 2 ) ^ dataPtrL[ 14 ] ) & borderMaskL; + sL[ 15 ] = ( ( s4L >> 3 ) ^ dataPtrL[ 15 ] ) & borderMaskL; + + /* parallel bit counting of patchHeightE - 2 features */ + + vL = 0; + + mL = ( ( sL[ 0 ] & 0x11111111 ) + ( sL[ 1 ] & 0x11111111 ) + ( sL[ 2 ] & 0x11111111 ) + + ( sL[ 3 ] & 0x11111111 ) + ( sL[ 4 ] & 0x11111111 ) + ( sL[ 5 ] & 0x11111111 ) + + ( sL[ 6 ] & 0x11111111 ) + ( sL[ 7 ] & 0x11111111 ) + ( sL[ 8 ] & 0x11111111 ) + + ( sL[ 9 ] & 0x11111111 ) + ( sL[ 10 ] & 0x11111111 ) + ( sL[ 11 ] & 0x11111111 ) + + ( sL[ 12 ] & 0x11111111 ) + ( sL[ 13 ] & 0x11111111 ) + ( sL[ 14 ] & 0x11111111 ) ); + + tL = dataPtrL[ 16 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 4; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ); + + mL = ( ( sL[ 0 ] & 0x02222222 ) + ( sL[ 1 ] & 0x02222222 ) + ( sL[ 2 ] & 0x02222222 ) + + ( sL[ 3 ] & 0x02222222 ) + ( sL[ 4 ] & 0x02222222 ) + ( sL[ 5 ] & 0x02222222 ) + + ( sL[ 6 ] & 0x02222222 ) + ( sL[ 7 ] & 0x02222222 ) + ( sL[ 8 ] & 0x02222222 ) + + ( sL[ 9 ] & 0x02222222 ) + ( sL[ 10 ] & 0x02222222 ) + ( sL[ 11 ] & 0x02222222 ) + + ( sL[ 12 ] & 0x02222222 ) + ( sL[ 13 ] & 0x02222222 ) + ( sL[ 14 ] & 0x02222222 ) ) >> 1; + + sL[ 15 ] >>= 1; + tL = dataPtrL[ 17 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 3; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ) << 1; + + mL = ( ( sL[ 0 ] & 0x04444444 ) + ( sL[ 1 ] & 0x04444444 ) + ( sL[ 2 ] & 0x04444444 ) + + ( sL[ 3 ] & 0x04444444 ) + ( sL[ 4 ] & 0x04444444 ) + ( sL[ 5 ] & 0x04444444 ) + + ( sL[ 6 ] & 0x04444444 ) + ( sL[ 7 ] & 0x04444444 ) + ( sL[ 8 ] & 0x04444444 ) + + ( sL[ 9 ] & 0x04444444 ) + ( sL[ 10 ] & 0x04444444 ) + ( sL[ 11 ] & 0x04444444 ) + + ( sL[ 12 ] & 0x04444444 ) + ( sL[ 13 ] & 0x04444444 ) + ( sL[ 14 ] & 0x04444444 ) ) >> 2; + + sL[ 15 ] >>= 1; + tL = dataPtrL[ 18 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 2; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ) << 2; + + mL = ( ( sL[ 0 ] & 0x08888888 ) + ( sL[ 1 ] & 0x08888888 ) + ( sL[ 2 ] & 0x08888888 ) + + ( sL[ 3 ] & 0x08888888 ) + ( sL[ 4 ] & 0x08888888 ) + ( sL[ 5 ] & 0x08888888 ) + + ( sL[ 6 ] & 0x08888888 ) + ( sL[ 7 ] & 0x08888888 ) + ( sL[ 8 ] & 0x08888888 ) + + ( sL[ 9 ] & 0x08888888 ) + ( sL[ 10 ] & 0x08888888 ) + ( sL[ 11 ] & 0x08888888 ) + + ( sL[ 12 ] & 0x08888888 ) + ( sL[ 13 ] & 0x08888888 ) + ( sL[ 14 ] & 0x08888888 ) ) >> 3; + + sL[ 15 ] >>= 1; + tL = dataPtrL[ 19 ]; + + /* compare with thresholds and store results in vL */ + vL |= ( ( ( mL & 0x0F0F0F0F ) + ( tL & 0x0F0F0F0F ) + ( sL[ 15 ] & 0x01010101 ) ) & 0x10101010 ) >> 1; + vL |= ( ( ( ( mL >> 4 ) & 0x0F0F0F0F ) + ( ( tL >> 4 ) & 0x0F0F0F0F ) + ( ( sL[ 15 ] >> 4 ) & 0x01010101 ) ) & 0x10101010 ) << 3; + + vL = ~vL; + + { + uint32 vmL; + vmL = vL & dataPtrL[ 20 ]; + bL[ 0 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 21 ]; + bL[ 1 ] += bbf_BIT_SUM_32( vmL); + vmL = vL & dataPtrL[ 22 ]; + bL[ 2 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 23 ]; + bL[ 3 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 24 ]; + bL[ 4 ] += bbf_BIT_SUM_32( vmL ); + vmL = vL & dataPtrL[ 25 ]; + bL[ 5 ] += bbf_BIT_SUM_32( vmL ); + } + + dataPtrL += 26; + } + } + + /* compute final activity */ + { + uint32 actL = ( ( bL[ 0 ] << 5 ) + ( bL[ 1 ] << 4 ) + ( bL[ 2 ] << 3 ) + + ( bL[ 3 ] << 2 ) + ( bL[ 4 ] << 1 ) + ( bL[ 5 ] ) ); + + return actL * ptrL->activityFactorE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.h b/Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.h new file mode 100644 index 0000000..a3d0677 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/L06DnsNx4x4Ftr.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_L06_DNS_NX4X4_FTR_EM_H +#define bbf_L06_DNS_NX4X4_FTR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_L06_DNS_NX4X4_FTR_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_L06DnsNx4x4Ftr +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** base element */ + struct bbf_Feature baseE; + + /** number of layers */ + uint32 layersE; + + /** data array */ + struct bbs_UInt32Arr dataArrE; + + /** factor to convert activity to proper range */ + uint32 activityFactorE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_L06DnsNx4x4Ftr */ +void bbf_L06DnsNx4x4Ftr_init( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA ); + +/** resets bbf_L06DnsNx4x4Ftr */ +void bbf_L06DnsNx4x4Ftr_exit( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_L06DnsNx4x4Ftr_copy( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA, + const struct bbf_L06DnsNx4x4Ftr* srcPtrA ); + +/** equal operator */ +flag bbf_L06DnsNx4x4Ftr_equal( struct bbs_Context* cpA, + const struct bbf_L06DnsNx4x4Ftr* ptrA, + const struct bbf_L06DnsNx4x4Ftr* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_L06DnsNx4x4Ftr_memSize( struct bbs_Context* cpA, + const struct bbf_L06DnsNx4x4Ftr* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_L06DnsNx4x4Ftr_memWrite( struct bbs_Context* cpA, + const struct bbf_L06DnsNx4x4Ftr* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_L06DnsNx4x4Ftr_memRead( struct bbs_Context* cpA, + struct bbf_L06DnsNx4x4Ftr* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_L06DnsNx4x4Ftr_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_L06_DNS_NX4X4_FTR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/LocalScanDetector.c b/Embedded/common/src/b_BitFeatureEm/LocalScanDetector.c new file mode 100644 index 0000000..880dba3 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/LocalScanDetector.c @@ -0,0 +1,745 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_ImageEm/Functions.h" +#include "b_BitFeatureEm/LocalScanDetector.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/** applies PCA mapping + * Input and output clusters may be identical + */ +void bbf_LocalScanDetector_pcaMap( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, + const struct bts_IdCluster2D* inClusterPtrA, + struct bts_IdCluster2D* outClusterPtrA ) +{ + bbs_DEF_fNameL( "bbf_LocalScanDetector_pcaMap" ) + + struct bts_Cluster2D* tmpCl1PtrL = ( struct bts_Cluster2D* )&ptrA->tmpCluster1E; + struct bts_Cluster2D* tmpCl2PtrL = ( struct bts_Cluster2D* )&ptrA->tmpCluster2E; + struct bts_RBFMap2D* rbfPtrL = ( struct bts_RBFMap2D* )&ptrA->rbfMapE; + struct bts_Flt16Alt2D altL; + uint32 outBbpL = inClusterPtrA->clusterE.bbpE; + uint32 iL, jL; + + /* setup two equivalent clusters holding the essential (alt-free) moves to be handled by PCA */ + bts_IdCluster2D_convertToEqivalentClusters( cpA, + inClusterPtrA, + &ptrA->pcaClusterE, + tmpCl1PtrL, + tmpCl2PtrL ); + + altL = bts_Cluster2D_alt( cpA, tmpCl1PtrL, tmpCl2PtrL, bts_ALT_RIGID ); + bts_Cluster2D_transform( cpA, tmpCl1PtrL, altL ); + bts_RBFMap2D_compute( cpA, rbfPtrL, tmpCl2PtrL, tmpCl1PtrL ); + bts_RBFMap2D_mapCluster( cpA, rbfPtrL, &ptrA->pcaClusterE.clusterE, tmpCl1PtrL, 6/* ! */ ); + + /* PCA projection: cluster1 -> cluster1 */ + { + /* mat elements: 8.8 */ + const int16* matPtrL = ptrA->pcaMatE.arrPtrE; + + /* same bbp as pca cluster */ + const int16* avgPtrL = ptrA->pcaAvgE.arrPtrE; + + struct bts_Int16Vec2D* vecArrL = tmpCl1PtrL->vecArrE; + + /* projected vector */ + int32 prjVecL[ bpi_LOCAL_SCAN_DETECTOR_MAX_PCA_DIM ]; + + /* width of matrix */ + uint16 matWidthL = tmpCl1PtrL->sizeE * 2; + + if( ptrA->pcaDimSubSpaceE > bpi_LOCAL_SCAN_DETECTOR_MAX_PCA_DIM ) + { + bbs_ERROR1( "%s:\nbpi_RF_LANDMARKER_MAX_PCA_DIM exceeded", fNameL ); + return; + } + + /* forward trafo */ + for( iL = 0; iL < ptrA->pcaDimSubSpaceE; iL++ ) + { + int32 sumL = 0; + avgPtrL = ptrA->pcaAvgE.arrPtrE; + for( jL = 0; jL < tmpCl1PtrL->sizeE; jL++ ) + { + sumL += matPtrL[ 0 ] * ( vecArrL[ jL ].xE - avgPtrL[ 0 ] ); + sumL += matPtrL[ 1 ] * ( vecArrL[ jL ].yE - avgPtrL[ 1 ] ); + avgPtrL += 2; + matPtrL += 2; + } + prjVecL[ iL ] = ( sumL + 128 ) >> 8; + } + + matPtrL = ptrA->pcaMatE.arrPtrE; + avgPtrL = ptrA->pcaAvgE.arrPtrE; + vecArrL = tmpCl1PtrL->vecArrE; + + /* backward trafo */ + for( jL = 0; jL < tmpCl1PtrL->sizeE; jL++ ) + { + int32 sumL = 0; + for( iL = 0; iL < ptrA->pcaDimSubSpaceE; iL++ ) + { + sumL += matPtrL[ iL * matWidthL + 0 ] * prjVecL[ iL ]; + } + + vecArrL[ jL ].xE = ( ( sumL + 128 ) >> 8 ) + avgPtrL[ 0 ]; + + sumL = 0; + for( iL = 0; iL < ptrA->pcaDimSubSpaceE; iL++ ) + { + sumL += matPtrL[ iL * matWidthL + 1 ] * prjVecL[ iL ]; + } + + vecArrL[ jL ].yE = ( ( sumL + 128 ) >> 8 ) + avgPtrL[ 1 ]; + + matPtrL += 2; + avgPtrL += 2; + } + } + + /* ALT backtransformation */ + bts_IdCluster2D_copy( cpA, outClusterPtrA, &ptrA->pcaClusterE ); + bts_Cluster2D_copyTransform( cpA, &outClusterPtrA->clusterE, tmpCl1PtrL, bts_Flt16Alt2D_inverted( &altL ), outBbpL ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanDetector_init( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA ) +{ + bbs_memset16( ptrA->ftrPtrArrE, 0, bbs_SIZEOF16( ptrA->ftrPtrArrE ) ); + bts_RBFMap2D_init( cpA, &ptrA->rbfMapE ); + bts_Cluster2D_init( cpA, &ptrA->tmpCluster1E ); + bts_Cluster2D_init( cpA, &ptrA->tmpCluster2E ); + bts_Cluster2D_init( cpA, &ptrA->tmpCluster3E ); + bts_Cluster2D_init( cpA, &ptrA->tmpCluster4E ); + bbf_LocalScanner_init( cpA, &ptrA->scannerE ); + bbs_Int32Arr_init( cpA, &ptrA->actArrE ); + bbs_Int16Arr_init( cpA, &ptrA->idxArrE ); + bbs_UInt8Arr_init( cpA, &ptrA->workImageBufE ); + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->scanWidthE = 0; + ptrA->scanHeightE = 0; + ptrA->scaleExpE = 0; + ptrA->interpolatedWarpingE = TRUE; + ptrA->warpScaleThresholdE = 0; + bts_IdCluster2D_init( cpA, &ptrA->refClusterE ); + bts_Cluster2D_init( cpA, &ptrA->scanClusterE ); + bbs_UInt16Arr_init( cpA, &ptrA->ftrDataArrE ); + bbf_BitParam_init( cpA, &ptrA->bitParamE ); + ptrA->outlierDistanceE = 0; + bts_IdCluster2D_init( cpA, &ptrA->pcaClusterE ); + bbs_Int16Arr_init( cpA, &ptrA->pcaAvgE ); + bbs_Int16Arr_init( cpA, &ptrA->pcaMatE ); + ptrA->pcaDimSubSpaceE = 0; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanDetector_exit( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA ) +{ + uint16 iL; + for( iL = 0; iL < ptrA->scanClusterE.sizeE; iL++ ) bbf_featureExit( cpA, ptrA->ftrPtrArrE[ iL ] ); + bbs_memset16( ptrA->ftrPtrArrE, 0, bbs_SIZEOF16( ptrA->ftrPtrArrE ) ); + + bts_RBFMap2D_exit( cpA, &ptrA->rbfMapE ); + bts_Cluster2D_exit( cpA, &ptrA->tmpCluster1E ); + bts_Cluster2D_exit( cpA, &ptrA->tmpCluster2E ); + bts_Cluster2D_exit( cpA, &ptrA->tmpCluster3E ); + bts_Cluster2D_exit( cpA, &ptrA->tmpCluster4E ); + bbf_LocalScanner_exit( cpA, &ptrA->scannerE ); + bbs_Int32Arr_exit( cpA, &ptrA->actArrE ); + bbs_Int16Arr_exit( cpA, &ptrA->idxArrE ); + bbs_UInt8Arr_exit( cpA, &ptrA->workImageBufE ); + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->scanWidthE = 0; + ptrA->scanHeightE = 0; + ptrA->scaleExpE = 0; + ptrA->interpolatedWarpingE = TRUE; + ptrA->warpScaleThresholdE = 0; + bts_IdCluster2D_exit( cpA, &ptrA->refClusterE ); + bts_Cluster2D_exit( cpA, &ptrA->scanClusterE ); + bbs_UInt16Arr_exit( cpA, &ptrA->ftrDataArrE ); + bbf_BitParam_exit( cpA, &ptrA->bitParamE ); + ptrA->outlierDistanceE = 0; + bts_IdCluster2D_exit( cpA, &ptrA->pcaClusterE ); + bbs_Int16Arr_exit( cpA, &ptrA->pcaAvgE ); + bbs_Int16Arr_exit( cpA, &ptrA->pcaMatE ); + ptrA->pcaDimSubSpaceE = 0; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanDetector_copy( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA, + const struct bbf_LocalScanDetector* srcPtrA ) +{ + bbs_ERROR0( "bbf_LocalScanDetector_copy:\n Function is not available" ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_LocalScanDetector_equal( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, + const struct bbf_LocalScanDetector* srcPtrA ) +{ + bbs_ERROR0( "bbf_LocalScanDetector_equal:\n Function is not available" ); + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanDetector_memSize( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA ) +{ + uint32 iL; + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbs_SIZEOF16( ptrA->patchWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->patchHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->scanWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->scanHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->scaleExpE ); + memSizeL += bbs_SIZEOF16( ptrA->interpolatedWarpingE ); + memSizeL += bbs_SIZEOF16( ptrA->warpScaleThresholdE ); + memSizeL += bts_IdCluster2D_memSize( cpA, &ptrA->refClusterE ); + memSizeL += bts_Cluster2D_memSize( cpA, &ptrA->scanClusterE ); + memSizeL += bbf_BitParam_memSize( cpA, &ptrA->bitParamE ); + memSizeL += bbs_SIZEOF16( ptrA->outlierDistanceE ); + memSizeL += bts_IdCluster2D_memSize( cpA, &ptrA->pcaClusterE ); + memSizeL += bbs_Int16Arr_memSize( cpA, &ptrA->pcaAvgE ); + memSizeL += bbs_Int16Arr_memSize( cpA, &ptrA->pcaMatE ); + memSizeL += bbs_SIZEOF16( ptrA->pcaDimSubSpaceE ); + memSizeL += bbs_SIZEOF16( ptrA->maxImageWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->maxImageHeightE ); + for( iL = 0; iL < ptrA->scanClusterE.sizeE; iL++ ) memSizeL += bbf_featureMemSize( cpA, ptrA->ftrPtrArrE[ iL ] ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanDetector_memWrite( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, + uint16* memPtrA ) +{ + uint32 iL; + uint32 memSizeL = bbf_LocalScanDetector_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_LOCAL_SCAN_DETECTOR_VERSION, memPtrA ); + + memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->scanWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->scanHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->scaleExpE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->interpolatedWarpingE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->warpScaleThresholdE, memPtrA ); + memPtrA += bts_IdCluster2D_memWrite( cpA, &ptrA->refClusterE, memPtrA ); + memPtrA += bts_Cluster2D_memWrite( cpA, &ptrA->scanClusterE, memPtrA ); + memPtrA += bbf_BitParam_memWrite( cpA, &ptrA->bitParamE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->outlierDistanceE, memPtrA ); + memPtrA += bts_IdCluster2D_memWrite( cpA, &ptrA->pcaClusterE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->pcaAvgE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->pcaMatE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->pcaDimSubSpaceE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxImageWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxImageHeightE, memPtrA ); + + for( iL = 0; iL < ptrA->scanClusterE.sizeE; iL++ ) memPtrA += bbf_featureMemWrite( cpA, ptrA->ftrPtrArrE[ iL ], memPtrA ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanDetector_memRead( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 iL; + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + struct bbs_MemSeg* sspL = bbs_MemTbl_sharedSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_LOCAL_SCAN_DETECTOR_VERSION, memPtrA ); + + + memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->scanWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->scanHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->scaleExpE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->interpolatedWarpingE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->warpScaleThresholdE, memPtrA ); + memPtrA += bts_IdCluster2D_memRead( cpA, &ptrA->refClusterE, memPtrA, espL ); + memPtrA += bts_Cluster2D_memRead( cpA, &ptrA->scanClusterE, memPtrA, espL ); + memPtrA += bbf_BitParam_memRead( cpA, &ptrA->bitParamE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->outlierDistanceE, memPtrA ); + memPtrA += bts_IdCluster2D_memRead( cpA, &ptrA->pcaClusterE, memPtrA, espL ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->pcaAvgE, memPtrA, espL ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->pcaMatE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->pcaDimSubSpaceE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxImageWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxImageHeightE, memPtrA ); + + /* check features & allocate data buffer */ + { + const uint16* memPtrL = memPtrA; + uint32 dataSizeL = 0; + for( iL = 0; iL < ptrA->scanClusterE.sizeE; iL++ ) + { + enum bbf_FeatureType typeL = ( enum bbf_FeatureType )bbs_memPeek32( memPtrL + 4 ); + dataSizeL += bbf_featureSizeOf16( cpA, typeL ); + memPtrL += bbs_memPeek32( memPtrL ); + } + bbs_UInt16Arr_create( cpA, &ptrA->ftrDataArrE, dataSizeL, espL ); + } + + /* load features & initialize pointers */ + { + uint16* dataPtrL = ptrA->ftrDataArrE.arrPtrE; + for( iL = 0; iL < ptrA->scanClusterE.sizeE; iL++ ) + { + enum bbf_FeatureType typeL = ( enum bbf_FeatureType )bbs_memPeek32( memPtrA + 4 ); + ptrA->ftrPtrArrE[ iL ] = ( struct bbf_Feature* )dataPtrL; + bbf_featureInit( cpA, ptrA->ftrPtrArrE[ iL ], typeL ); + memPtrA += bbf_featureMemRead( cpA, ptrA->ftrPtrArrE[ iL ], memPtrA, &memTblL ); + dataPtrL += bbf_featureSizeOf16( cpA, typeL ); + } + } + + if( memSizeL != bbf_LocalScanDetector_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_LocalScanDetector_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + if( ptrA->maxImageWidthE * ptrA->maxImageHeightE == 0 ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_LocalScanDetector_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "maximum image width/height not set" ); + return 0; + } + + /* initialize internal data */ + + /* ought to be placed on shared memory later */ + bts_RBFMap2D_create( cpA, &ptrA->rbfMapE, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + ptrA->rbfMapE.RBFTypeE = bts_RBF_LINEAR; + ptrA->rbfMapE.altTypeE = bts_ALT_RIGID; + + bts_Cluster2D_create( cpA, &ptrA->tmpCluster1E, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + bts_Cluster2D_create( cpA, &ptrA->tmpCluster2E, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + bts_Cluster2D_create( cpA, &ptrA->tmpCluster3E, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + bts_Cluster2D_create( cpA, &ptrA->tmpCluster4E, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + + bbs_Int32Arr_create( cpA, &ptrA->actArrE, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + bbs_Int16Arr_create( cpA, &ptrA->idxArrE, bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE, sspL ); + + /* working image memory */ + /* ought to be placed on shared memory later */ + bbs_UInt8Arr_create( cpA, &ptrA->workImageBufE, ptrA->maxImageWidthE * ptrA->maxImageHeightE, sspL ); + + /* initialize local scanner (be aware of shared memory usage when moving this create function) */ + bbf_LocalScanner_create( cpA, &ptrA->scannerE, + ptrA->patchWidthE, + ptrA->patchHeightE, + ptrA->scaleExpE, + ptrA->maxImageWidthE, + ptrA->maxImageHeightE, + ptrA->scaleExpE, + ptrA->bitParamE.outerRadiusE, + &memTblL ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_LocalScanDetector_process( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, + uint8* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_IdCluster2D* inClusterPtrA, + struct bts_IdCluster2D* outClusterPtrA ) +{ + bbs_DEF_fNameL( "bbf_LocalScanDetector_process" ) + + int32 pw0L = ptrA->patchWidthE; + int32 ph0L = ptrA->patchHeightE; + int32 pw1L = pw0L << ptrA->scaleExpE; + int32 ph1L = ph0L << ptrA->scaleExpE; + + struct bts_Cluster2D* wrkClPtrL = ( struct bts_Cluster2D* )&ptrA->tmpCluster1E; + struct bts_Cluster2D* refClPtrL = ( struct bts_Cluster2D* )&ptrA->tmpCluster2E; + struct bts_Cluster2D* dstClPtrL = ( struct bts_Cluster2D* )&ptrA->tmpCluster3E; + struct bts_Cluster2D* tmpClPtrL = ( struct bts_Cluster2D* )&ptrA->tmpCluster4E; + struct bts_RBFMap2D* rbfPtrL = ( struct bts_RBFMap2D* )&ptrA->rbfMapE; + struct bbf_LocalScanner* scnPtrL = ( struct bbf_LocalScanner* )&ptrA->scannerE; + + int32* actArrL = ( int32* )ptrA->actArrE.arrPtrE; + int16* idxArrL = ( int16* )ptrA->idxArrE.arrPtrE; + + uint32 workImageWidthL, workImageHeightL; + + struct bts_Flt16Alt2D altL; + + int32 confidenceL; + uint32 iL; + uint32 sizeL = ptrA->scanClusterE.sizeE; + + if( sizeL > bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE ) + { + bbs_ERROR1( "%s:\nScan cluster size exceeds bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE", fNameL ); + return 0; + } + + /* compute equivalent clusters (matching ids) from input and reference cluster */ + bts_IdCluster2D_convertToEqivalentClusters( cpA, inClusterPtrA, &ptrA->refClusterE, wrkClPtrL, refClPtrL ); + + /* altL: orig image -> normalized image */ + altL = bts_Cluster2D_alt( cpA, wrkClPtrL, refClPtrL, bts_ALT_RIGID ); + + /* transorm work cluster to normalized image */ + bts_Cluster2D_transformBbp( cpA, wrkClPtrL, altL, 6 ); + + /* map: ref cluster -> work cluster */ + bts_RBFMap2D_compute( cpA, rbfPtrL, refClPtrL, wrkClPtrL ); + + /* copy: scanClusterE -> work cluster */ + bts_Cluster2D_copy( cpA, wrkClPtrL, &ptrA->scanClusterE ); + + /* copy: refClusterE -> ref cluster */ + bts_Cluster2D_copy( cpA, refClPtrL, &ptrA->refClusterE.clusterE ); + + /* apply map to work cluster */ + bts_Cluster2D_rbfTransform( cpA, wrkClPtrL, rbfPtrL ); + + /* apply map to ref cluster */ + bts_Cluster2D_rbfTransform( cpA, refClPtrL, rbfPtrL ); + + { + /* analyze boundaries; get exact dimensions of working image */ + int32 workBorderWL = ( ( ptrA->scanWidthE + pw1L + 1 ) >> 1 ) + 1; /* add a pixel to ensure full search area */ + int32 workBorderHL = ( ( ptrA->scanHeightE + ph1L + 1 ) >> 1 ) + 1; /* add a pixel to ensure full search area */ + struct bts_Int16Rect workAreaL = bts_Cluster2D_boundingBox( cpA, wrkClPtrL ); + workAreaL.x1E = workAreaL.x1E >> wrkClPtrL->bbpE; + workAreaL.y1E = workAreaL.y1E >> wrkClPtrL->bbpE; + workAreaL.x2E = workAreaL.x2E >> wrkClPtrL->bbpE; + workAreaL.y2E = workAreaL.y2E >> wrkClPtrL->bbpE; + workAreaL.x1E -= workBorderWL; + workAreaL.y1E -= workBorderHL; + workAreaL.x2E += workBorderWL; + workAreaL.y2E += workBorderHL; + + workImageWidthL = workAreaL.x2E - workAreaL.x1E; + workImageHeightL = workAreaL.y2E - workAreaL.y1E; + + /* truncate if necessary (should not occur in normal operation) */ + workImageWidthL = workImageWidthL > ptrA->maxImageWidthE ? ptrA->maxImageWidthE : workImageWidthL; + workImageHeightL = workImageHeightL > ptrA->maxImageHeightE ? ptrA->maxImageHeightE : workImageHeightL; + + /* adjust ALT */ + altL.vecE.xE -= workAreaL.x1E << altL.vecE.bbpE; + altL.vecE.yE -= workAreaL.y1E << altL.vecE.bbpE; + + /* adjust work cluster */ + for( iL = 0; iL < wrkClPtrL->sizeE; iL++ ) + { + wrkClPtrL->vecArrE[ iL ].xE -= workAreaL.x1E << wrkClPtrL->bbpE; + wrkClPtrL->vecArrE[ iL ].yE -= workAreaL.y1E << wrkClPtrL->bbpE; + } + + /* adjust ref cluster */ + for( iL = 0; iL < wrkClPtrL->sizeE; iL++ ) + { + refClPtrL->vecArrE[ iL ].xE -= workAreaL.x1E << refClPtrL->bbpE; + refClPtrL->vecArrE[ iL ].yE -= workAreaL.y1E << refClPtrL->bbpE; + } + + /* transform image */ + bim_filterWarp( cpA, + ptrA->workImageBufE.arrPtrE, + imagePtrA, imageWidthA, imageHeightA, + offsPtrA, + &altL, + workImageWidthL, workImageHeightL, + NULL, + ptrA->warpScaleThresholdE, + ptrA->interpolatedWarpingE ); + + } + + /* scan over all positions of work cluster; target positions are stored in *dstClPtrL*/ + { + int32 regionWHL = ( ptrA->scanWidthE + pw1L + 1 ) >> 1; + int32 regionHHL = ( ptrA->scanHeightE + ph1L + 1 ) >> 1; + struct bts_Int16Vec2D* srcVecArrL = wrkClPtrL->vecArrE; + struct bts_Int16Vec2D* dstVecArrL = dstClPtrL->vecArrE; + int32 vecBbpL = wrkClPtrL->bbpE; + bts_Cluster2D_size( cpA, dstClPtrL, sizeL ); + dstClPtrL->bbpE = vecBbpL; + + /* initialize scanner */ + scnPtrL->patchWidthE = ptrA->patchWidthE; + scnPtrL->patchHeightE = ptrA->patchWidthE; + scnPtrL->scaleExpE = ptrA->scaleExpE; + + bbf_LocalScanner_assign( cpA, scnPtrL, ptrA->workImageBufE.arrPtrE, workImageWidthL, workImageHeightL, &ptrA->bitParamE ); + + bbs_memset32( actArrL, 0x80000000, sizeL ); + + do + { + for( iL = 0; iL < sizeL; iL++ ) + { + int32 bestActL = 0x80000000; + uint32 bestIdxL = 0; + struct bbf_Feature* ftrPtrL = ptrA->ftrPtrArrE[ iL ]; + + /* set scan region */ + { + int32 x0L = ( ( wrkClPtrL->vecArrE[ iL ].xE >> ( wrkClPtrL->bbpE - 1 ) ) + 1 ) >> 1; + int32 y0L = ( ( wrkClPtrL->vecArrE[ iL ].yE >> ( wrkClPtrL->bbpE - 1 ) ) + 1 ) >> 1; + struct bts_Int16Rect scanRegionL = bts_Int16Rect_create( x0L - regionWHL, y0L - regionHHL, x0L + regionWHL, y0L + regionHHL ); + bbf_LocalScanner_origScanRegion( cpA, scnPtrL, &scanRegionL ); + } + + do + { + int32 actL = ftrPtrL->vpActivityE( ftrPtrL, bbf_LocalScanner_getPatch( scnPtrL ) ); + + if( actL > bestActL ) + { + bestActL = actL; + bestIdxL = bbf_LocalScanner_scanIndex( scnPtrL ); + } + } + while( bbf_LocalScanner_next( cpA, scnPtrL ) ); + + { + int32 xL, yL; /* 16.16 */ + bbf_LocalScanner_idxPos( scnPtrL, bestIdxL, &xL, &yL ); + xL += pw1L << 15; + yL += ph1L << 15; + if( bestActL > actArrL[ iL ] ) + { + dstVecArrL[ iL ].xE = ( ( xL >> ( 15 - vecBbpL ) ) + 1 ) >> 1; + dstVecArrL[ iL ].yE = ( ( yL >> ( 15 - vecBbpL ) ) + 1 ) >> 1; + actArrL[ iL ] = bestActL; + } + } + } + } + while( bbf_LocalScanner_nextOffset( cpA, scnPtrL ) ); + + /* outlier analysis: outliers are disabled by setting their similarity to -1 */ + if( ptrA->outlierDistanceE > 0 ) + { + /* altL: work cluster -> ref cluster */ + struct bts_Flt16Alt2D localAltL = bts_Cluster2D_alt( cpA, wrkClPtrL, dstClPtrL, bts_ALT_RIGID ); + + /* squared distance 16.16 */ + uint32 dist2L = ( ptrA->outlierDistanceE >> 8 ) * ( ptrA->outlierDistanceE >> 8 ); + + /* analyze deviations */ + for( iL = 0; iL < sizeL; iL++ ) + { + struct bts_Flt16Vec2D vecL = bts_Flt16Vec2D_create32( srcVecArrL[ iL ].xE, srcVecArrL[ iL ].yE, vecBbpL ); + uint32 dev2L; /* squared deviation 16.16 */ + vecL = bts_Flt16Alt2D_mapFlt( &localAltL, &vecL ); + vecL = bts_Flt16Vec2D_sub( vecL, bts_Flt16Vec2D_create32( dstVecArrL[ iL ].xE, dstVecArrL[ iL ].yE, vecBbpL ) ); + dev2L = bbs_convertU32( bts_Flt16Vec2D_norm2( &vecL ), vecL.bbpE << 1, 16 ); + if( dev2L > dist2L ) actArrL[ iL ] = 0xF0000000; + } + } + + /* remove undetected positions but keep at least 1/2 best positions */ + { + flag sortedL; + + /* bubble sort (no speed issue in this case) */ + for( iL = 0; iL < sizeL; iL++ ) idxArrL[ iL ] = iL; + + do + { + sortedL = TRUE; + for( iL = 1; iL < sizeL; iL++ ) + { + if( actArrL[ idxArrL[ iL - 1 ] ] < actArrL[ idxArrL[ iL ] ] ) + { + int16 tmpL = idxArrL[ iL - 1 ]; + idxArrL[ iL - 1 ] = idxArrL[ iL ]; + idxArrL[ iL ] = tmpL; + sortedL = FALSE; + } + } + } + while( !sortedL ); + + for( iL = ( sizeL >> 1 ); iL < sizeL && actArrL[ idxArrL[ iL ] ] >= 0; iL++ ); + + { + uint32 subSizeL = iL; + + /* reorder clusters */ + bts_Cluster2D_size( cpA, tmpClPtrL, subSizeL ); + { + struct bts_Int16Vec2D* tmpVecArrL = tmpClPtrL->vecArrE; + for( iL = 0; iL < subSizeL; iL++ ) tmpVecArrL[ iL ] = srcVecArrL[ idxArrL[ iL ] ]; + for( iL = 0; iL < subSizeL; iL++ ) srcVecArrL[ iL ] = tmpVecArrL[ iL ]; + for( iL = 0; iL < subSizeL; iL++ ) tmpVecArrL[ iL ] = dstVecArrL[ idxArrL[ iL ] ]; + for( iL = 0; iL < subSizeL; iL++ ) dstVecArrL[ iL ] = tmpVecArrL[ iL ]; + } + bts_Cluster2D_size( cpA, wrkClPtrL, subSizeL ); + bts_Cluster2D_size( cpA, dstClPtrL, subSizeL ); + } + } + + /* compute confidence */ + { + int16* idxArrL = ptrA->idxArrE.arrPtrE; + int32* actArrL = ptrA->actArrE.arrPtrE; + int32 actSumL = 0; /* .20 */ + for( iL = 0; iL < sizeL; iL++ ) + { + float actL = ( actArrL[ idxArrL[ iL ] ] + 128 ) >> 8; + if( actL < 0 ) break; + actSumL += actL; + } + + /* actSumL = average positive activity */ + actSumL = ( iL > 0 ) ? actSumL / iL : 0; + + confidenceL = ( ( ( int32 )iL << 20 ) - ( ( ( int32 )1 << 20 ) - actSumL ) ) / sizeL; + + /* adjust to 4.28 */ + confidenceL <<= 8; + } + + } + + /* map: wrkCluster -> dstCluster */ + bts_RBFMap2D_compute( cpA, rbfPtrL, wrkClPtrL, dstClPtrL ); + + /* apply map to ref cluster */ + bts_Cluster2D_rbfTransform( cpA, refClPtrL, rbfPtrL ); + + /* copy ref cluster to outCluster */ + bts_Cluster2D_copy( cpA, &outClusterPtrA->clusterE, refClPtrL ); + bbs_Int16Arr_copy( cpA, &outClusterPtrA->idArrE, &ptrA->refClusterE.idArrE ); + + /* PCA Mapping */ + if( ptrA->pcaDimSubSpaceE > 0 ) + { + bbf_LocalScanDetector_pcaMap( cpA, ptrA, outClusterPtrA, outClusterPtrA ); + } + + /* backtransform out cluster to original image */ + bts_Cluster2D_transformBbp( cpA, &outClusterPtrA->clusterE, bts_Flt16Alt2D_inverted( &altL ), inClusterPtrA->clusterE.bbpE ); + + return confidenceL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/LocalScanDetector.h b/Embedded/common/src/b_BitFeatureEm/LocalScanDetector.h new file mode 100644 index 0000000..a4408f4 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/LocalScanDetector.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_LOCAL_SCAN_DETECTOR_EM_H +#define bbf_LOCAL_SCAN_DETECTOR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/IdCluster2D.h" +#include "b_BitFeatureEm/Sequence.h" +#include "b_BitFeatureEm/BitParam.h" +#include "b_BitFeatureEm/LocalScanner.h" +#include "b_TensorEm/RBFMap2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_LOCAL_SCAN_DETECTOR_VERSION 100 + +/* maximum number of features in scan detector */ +#define bbf_LOCAL_SCAN_DETECTOR_MAX_FEATURES 16 + +/* maximum size of any cluster in all processing stages of landmarker */ +#define bpi_LOCAL_SCAN_DETECTOR_MAX_CLUSTER_SIZE 24 + +/* maximum dimension of PCA subspace */ +#define bpi_LOCAL_SCAN_DETECTOR_MAX_PCA_DIM 12 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_LocalScanDetector +{ + /* ---- private data --------------------------------------------------- */ + + /** feature pointer arrray */ + struct bbf_Feature* ftrPtrArrE[ bbf_LOCAL_SCAN_DETECTOR_MAX_FEATURES ]; + + /** multiple purpose rbf map */ + struct bts_RBFMap2D rbfMapE; + + /** temporary cluster */ + struct bts_Cluster2D tmpCluster1E; + + /** temporary cluster */ + struct bts_Cluster2D tmpCluster2E; + + /** temporary cluster */ + struct bts_Cluster2D tmpCluster3E; + + /** temporary cluster */ + struct bts_Cluster2D tmpCluster4E; + + /** local scanner */ + struct bbf_LocalScanner scannerE; + + /** activity array */ + struct bbs_Int32Arr actArrE; + + /** index array */ + struct bbs_Int16Arr idxArrE; + + /** working image buffer */ + struct bbs_UInt8Arr workImageBufE; + + /* ---- public data ---------------------------------------------------- */ + + /** patch width */ + uint32 patchWidthE; + + /** patch height*/ + uint32 patchHeightE; + + /** width of scan area */ + uint32 scanWidthE; + + /** height of scan area */ + uint32 scanHeightE; + + /** scanner scale exponent */ + uint32 scaleExpE; + + /** interpolated image warping */ + flag interpolatedWarpingE; + + /** image downscale threshold (part of image warping) (16.16) */ + uint32 warpScaleThresholdE; + + /** reference cluster */ + struct bts_IdCluster2D refClusterE; + + /** cluster with scan positions */ + struct bts_Cluster2D scanClusterE; + + /** feature data array (contains feature elements) */ + struct bbs_UInt16Arr ftrDataArrE; + + /** parameter for bit generation */ + struct bbf_BitParam bitParamE; + + /** outlier distance in pixels (16.16); ( >0: activates outlier analysis ) */ + uint32 outlierDistanceE; + + /** pca reference cluster */ + struct bts_IdCluster2D pcaClusterE; + + /** pca average vector (10.6) */ + struct bbs_Int16Arr pcaAvgE; + + /** pca projection matrix (8.8) */ + struct bbs_Int16Arr pcaMatE; + + /** pcs subspace dimensions */ + uint32 pcaDimSubSpaceE; + + /** max width of working image */ + uint32 maxImageWidthE; + + /** max height of working image */ + uint32 maxImageHeightE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_LocalScanDetector */ +void bbf_LocalScanDetector_init( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA ); + +/** resets bbf_LocalScanDetector */ +void bbf_LocalScanDetector_exit( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_LocalScanDetector_copy( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA, + const struct bbf_LocalScanDetector* srcPtrA ); + +/** equal operator */ +flag bbf_LocalScanDetector_equal( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, + const struct bbf_LocalScanDetector* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_LocalScanDetector_memSize( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_LocalScanDetector_memWrite( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_LocalScanDetector_memRead( struct bbs_Context* cpA, + struct bbf_LocalScanDetector* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** processes image with cluster; produces output cluster and returns confidence (8.24) + * offsPtrA specifies pixel position (0,0) in input image + */ +int32 bbf_LocalScanDetector_process( struct bbs_Context* cpA, + const struct bbf_LocalScanDetector* ptrA, + uint8* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_IdCluster2D* inClusterPtrA, + struct bts_IdCluster2D* outClusterPtrA ); + +#endif /* bbf_LOCAL_SCAN_DETECTOR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/LocalScanner.c b/Embedded/common/src/b_BitFeatureEm/LocalScanner.c new file mode 100644 index 0000000..ed0c0e1 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/LocalScanner.c @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/LocalScanner.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/** allocates arays */ +void bbf_LocalScanner_alloc( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + struct bbs_MemTbl* mtpA ) +{ + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + struct bbs_MemSeg* sspL = bbs_MemTbl_sharedSegPtr( cpA, &memTblL, 0 ); + + /* filter patch dimension */ + uint32 proL = ptrA->maxRadiusE; + uint32 pwoL = ( proL << 1 ) + 1; + + /* output image size (bit image) */ + uint32 woL = ptrA->maxImageWidthE; + uint32 hoL = ptrA->maxImageHeightE; + + if( ptrA->minScaleExpE > 0 ) + { + /* allocate working image */ + bbs_UInt8Arr_create( cpA, &ptrA->workImageBufferE, ( woL >> 1 ) * ( hoL >> 1 ), espL ); + bbs_UInt8Arr_fill( cpA, &ptrA->workImageBufferE, 0 ); + } + + /* allocate bit image */ + bim_UInt32Image_create( cpA, &ptrA->bitImageE, woL, ( hoL >> 5 ) + ( ( ( hoL & 0x1F ) != 0 ) ? 1 : 0 ), espL ); + bim_UInt32Image_setAllPixels( cpA, &ptrA->bitImageE, 0, 0 ); + + /* allocate patch buffer */ + bbs_UInt32Arr_create( cpA, &ptrA->patchBufferE, ptrA->bitImageE.widthE, espL ); + bbs_UInt32Arr_fill( cpA, &ptrA->patchBufferE, 0 ); + + /* allocate table */ + bim_UInt32Image_create( cpA, &ptrA->satE, woL + pwoL, pwoL + 1, sspL ); +} + +/* ------------------------------------------------------------------------- */ + +/** downscales original image by factor 2 */ +void bbf_LocalScanner_downscale0( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + int32 w0L = ptrA->origWidthE; + int32 h0L = ptrA->origHeightE; + + int32 w1L = ( w0L - ptrA->xOffE ) >> 1; + int32 h1L = ( h0L - ptrA->yOffE ) >> 1; + + const uint8* iArrL = ptrA->origImagePtrE + ptrA->xOffE + ptrA->yOffE * w0L; + uint8* oArrL = ptrA->workImageBufferE.arrPtrE; + + int32 iL, jL; + int32 kL = 0; + + bbs_UInt8Arr_size( cpA, &ptrA->workImageBufferE, w1L * h1L ); + ptrA->workImagePtrE = ptrA->workImageBufferE.arrPtrE; + ptrA->workWidthE = w1L; + ptrA->workHeightE = h1L; + + for( jL = 0; jL < h1L; jL++ ) + { + for( iL = 0; iL < w1L; iL++ ) + { + int32 idxL = jL * 2 * w0L + iL * 2; + oArrL[ kL++ ] = ( ( uint32 )iArrL[ idxL ] + + iArrL[ idxL + 1 ] + + iArrL[ idxL + w0L ] + + iArrL[ idxL + w0L + 1 ] + 2 ) >> 2; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/** downscales work image by factor 2 */ +void bbf_LocalScanner_downscale1( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + int32 w0L = ptrA->workWidthE; + int32 h0L = ptrA->workHeightE; + int32 w1L = w0L >> 1; + int32 h1L = h0L >> 1; + + uint8* arrL = ptrA->workImageBufferE.arrPtrE; + + int32 iL, jL; + int32 kL = 0; + + for( jL = 0; jL < h1L; jL++ ) + { + for( iL = 0; iL < w1L; iL++ ) + { + int32 idxL = jL * 2 * w0L + iL * 2; + arrL[ kL++ ] = ( ( uint32 )arrL[ idxL ] + + arrL[ idxL + 1 ] + + arrL[ idxL + w0L ] + + arrL[ idxL + w0L + 1 ] + 2 ) >> 2; + } + } + + ptrA->workWidthE = w1L; + ptrA->workHeightE = h1L; +} + +/* ------------------------------------------------------------------------- */ + +/** downscales by factor 2 */ +void bbf_LocalScanner_downscale( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + uint32 iL; + if( ptrA->scaleExpE > 0 ) bbf_LocalScanner_downscale0( cpA, ptrA ); + for( iL = 1; iL < ptrA->scaleExpE; iL++ ) bbf_LocalScanner_downscale1( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/** computes bit image */ +void bbf_LocalScanner_createBitImage( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + bbs_DEF_fNameL( "void bbf_LocalScanner_createBitImage( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )" ) + + uint32 iL, jL; + + uint32 proL = ptrA->bitParamE.outerRadiusE; + uint32 priL = ptrA->bitParamE.innerRadiusE; + uint32 pwoL = ( proL << 1 ) + 1; + uint32 pwiL = ( priL << 1 ) + 1; + + /* areas of inner and outer rectangles */ + uint32 poAreaL = pwoL * pwoL; + uint32 piAreaL = pwiL * pwiL; + + uint32 wL, hL; /* input image size */ + + uint32 wsL, hsL; + uint32* satL; + uint32 satSizeL; + uint32 swi1L = 0; /* writing index */ + uint32 swi2L = 0; /* writing index */ + uint32 sriL = 0; /* reading index */ + uint32 siL[ 8 ]; + + uint32 bitMaskL; + uint32* bitRowL; + + + if( proL <= priL ) + { + bbs_ERROR1( "%s:\n outer radius <= inner radius", fNameL ); + return; + } + + /* input image size */ + wL = ptrA->workWidthE; + hL = ptrA->workHeightE; + + if( wL <= pwoL || hL <= pwoL ) + { + bbs_ERROR1( "%s:\n image is too small", fNameL ); + return; + } + + ptrA->currentWidthE = wL; + ptrA->currentHeightE = hL; + + /* reset scan region */ + ptrA->workScanRegionE = bts_Int16Rect_create( 0, 0, ptrA->currentWidthE, ptrA->currentHeightE ); + + /* initialize bit image */ + bim_UInt32Image_size( cpA, &ptrA->bitImageE, wL, ( hL >> 5 ) + ( ( ( hL & 0x1F ) != 0 ) ? 1 : 0 ) ); + bim_UInt32Image_setAllPixels( cpA, &ptrA->bitImageE, 0, 0 ); + + bitMaskL = 1; + bitRowL = ( uint32* )ptrA->bitImageE.arrE.arrPtrE; + + /* width of table */ + wsL = wL + pwoL; + + /* height of table */ + hsL = pwoL + 1; + + bim_UInt32Image_size( cpA, &ptrA->satE, wsL, hsL ); + + satL = ( uint32* )ptrA->satE.arrE.arrPtrE; + satSizeL = ptrA->satE.arrE.sizeE; + + /* compute table and bit image */ + for( iL = wsL * ( proL + 1 ); iL > 0; iL-- ) satL[ swi1L++ ] = 0; + swi2L = swi1L - wsL; + + for( jL = 0; jL < hL + proL; jL++ ) + { + if( jL < hL ) /* rescale area */ + { + const uint8* arr0L = &ptrA->workImagePtrE[ jL * wL ]; + uint32 hSumL = 0; + for( iL = 0; iL <= proL; iL++ ) satL[ swi1L++ ] = 0; + swi2L += iL; + for( iL = 0; iL < wL; iL++ ) satL[ swi1L++ ] = ( hSumL += arr0L[ iL ] ) + satL[ swi2L++ ]; + for( iL = 0; iL < proL; iL++ ) satL[ swi1L++ ] = hSumL + satL[ swi2L++ ]; + } + else /* image is processed - fill in 0s */ + { + for( iL = 0; iL < wsL; iL++ ) satL[ swi1L++ ] = satL[ swi2L++ ]; + } + + swi1L = ( swi1L < satSizeL ) ? swi1L : 0; + swi2L = ( swi2L < satSizeL ) ? swi2L : 0; + + /* fill line in bit image */ + if( jL >= proL ) + { + const uint32* rSatL = satL; + + /* table coordinate indices for outer rectangle */ + siL[ 0 ] = sriL; + siL[ 1 ] = siL[ 0 ] + pwoL; + siL[ 2 ] = siL[ 0 ] + pwoL * wsL; + siL[ 2 ] -= ( siL[ 2 ] >= satSizeL ) ? satSizeL : 0; + siL[ 3 ] = siL[ 2 ] + pwoL; + + /* table coordinate indices for inner rectangle */ + siL[ 4 ] = siL[ 0 ] + ( proL - priL ) * wsL + ( proL - priL ); + siL[ 4 ] -= ( siL[ 4 ] >= satSizeL ) ? satSizeL : 0; + siL[ 5 ] = siL[ 4 ] + pwiL; + siL[ 6 ] = siL[ 4 ] + pwiL * wsL; + siL[ 6 ] -= ( siL[ 6 ] >= satSizeL ) ? satSizeL : 0; + siL[ 7 ] = siL[ 6 ] + pwiL; + sriL += wsL; + if( sriL == satSizeL ) sriL = 0; + + for( iL = 0; iL < wL; iL++ ) + { + uint32 oAvgL = ( rSatL[ siL[ 0 ] ] - rSatL[ siL[ 1 ] ] - rSatL[ siL[ 2 ] ] + rSatL[ siL[ 3 ] ] ) * piAreaL; + uint32 iAvgL = ( rSatL[ siL[ 4 ] ] - rSatL[ siL[ 5 ] ] - rSatL[ siL[ 6 ] ] + rSatL[ siL[ 7 ] ] ) * poAreaL; + bitRowL[ iL ] |= ( iAvgL > oAvgL ) ? bitMaskL : 0; + rSatL++; + } + if( ( bitMaskL <<= 1 ) == 0 ) + { + bitRowL += wL; + bitMaskL = 1; + } + } + } +} + +/* -------------------------------------------------------------------------- */ + +/** inilialize patch buffer */ +void bbf_LocalScanner_initPatchBuffer( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + int32 ybL = ptrA->workScanRegionE.y1E >> 5; + int32 yoL = ptrA->workScanRegionE.y1E & 0x1F; + int32 xbL = ptrA->workScanRegionE.x1E; + uint32 wsrWidthL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E; + + bbs_UInt32Arr_size( cpA, &ptrA->patchBufferE, ptrA->bitImageE.widthE ); + + if( yoL == 0 ) + { + bbs_memcpy32( ptrA->patchBufferE.arrPtrE + xbL, + ptrA->bitImageE.arrE.arrPtrE + ybL * ptrA->bitImageE.widthE + xbL, + wsrWidthL ); + } + else if( ybL == ( int32 )ptrA->bitImageE.heightE - 1 ) + { + uint32* dstL = ptrA->patchBufferE.arrPtrE + xbL; + const uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + ybL * ptrA->bitImageE.widthE + xbL; + uint32 iL; + for( iL = 0; iL < wsrWidthL; iL++ ) dstL[ iL ] = srcL[ iL ] >> yoL; + } + else + { + uint32* dstL = ptrA->patchBufferE.arrPtrE + xbL; + const uint32* src0L = ptrA->bitImageE.arrE.arrPtrE + ybL * ptrA->bitImageE.widthE + xbL; + const uint32* src1L = src0L + ptrA->bitImageE.widthE; + uint32 iL; + uint32 slL = 32 - yoL; + for( iL = 0; iL < wsrWidthL; iL++ ) dstL[ iL ] = ( src0L[ iL ] >> yoL ) | ( src1L[ iL ] << slL ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* sets work scan region from original scan region according to scale exponent */ +void bbf_LocalScanner_setWorkScanRegion( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + int32 xMinL = ptrA->origScanRegionE.x1E >> ptrA->scaleExpE; + int32 yMinL = ptrA->origScanRegionE.y1E >> ptrA->scaleExpE; + int32 xMaxL = ptrA->origScanRegionE.x2E >> ptrA->scaleExpE; + int32 yMaxL = ptrA->origScanRegionE.y2E >> ptrA->scaleExpE; + ptrA->workScanRegionE.x1E = ( xMinL < 0 ) ? 0 : xMinL; + ptrA->workScanRegionE.y1E = ( yMinL < 0 ) ? 0 : yMinL; + ptrA->workScanRegionE.x2E = ( xMaxL > ( int32 )ptrA->currentWidthE ) ? ptrA->currentWidthE : xMaxL; + ptrA->workScanRegionE.y2E = ( yMaxL > ( int32 )ptrA->currentHeightE ) ? ptrA->currentHeightE : yMaxL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_init( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->xOffE = 0; + ptrA->yOffE = 0; + ptrA->currentWidthE = 0; + ptrA->currentHeightE = 0; + ptrA->workWidthE = 0; + ptrA->workHeightE = 0; + ptrA->workImagePtrE = NULL; + ptrA->origWidthE = 0; + ptrA->origHeightE = 0; + ptrA->origImagePtrE = NULL; + bbf_BitParam_init( cpA, &ptrA->bitParamE ); + bbs_UInt8Arr_init( cpA, &ptrA->workImageBufferE ); + bim_UInt32Image_init( cpA, &ptrA->satE ); + bim_UInt32Image_init( cpA, &ptrA->bitImageE ); + bbs_UInt32Arr_init( cpA, &ptrA->patchBufferE ); + bts_Int16Rect_init( cpA, &ptrA->origScanRegionE ); + bts_Int16Rect_init( cpA, &ptrA->workScanRegionE ); + + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->scaleExpE = 0; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + ptrA->minScaleExpE = 0; + ptrA->maxRadiusE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_exit( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->xOffE = 0; + ptrA->yOffE = 0; + ptrA->currentWidthE = 0; + ptrA->currentHeightE = 0; + ptrA->workWidthE = 0; + ptrA->workHeightE = 0; + ptrA->workImagePtrE = NULL; + ptrA->origWidthE = 0; + ptrA->origHeightE = 0; + ptrA->origImagePtrE = NULL; + bbf_BitParam_exit( cpA, &ptrA->bitParamE ); + bbs_UInt8Arr_exit( cpA, &ptrA->workImageBufferE ); + bim_UInt32Image_exit( cpA, &ptrA->satE ); + bim_UInt32Image_exit( cpA, &ptrA->bitImageE ); + bbs_UInt32Arr_exit( cpA, &ptrA->patchBufferE ); + bts_Int16Rect_exit( cpA, &ptrA->origScanRegionE ); + bts_Int16Rect_exit( cpA, &ptrA->workScanRegionE ); + + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->scaleExpE = 0; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + ptrA->minScaleExpE = 0; + ptrA->maxRadiusE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_copy( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const struct bbf_LocalScanner* srcPtrA ) +{ + bbs_ERROR0( "bbf_LocalScanner_copy:\n Function is not available" ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_LocalScanner_equal( struct bbs_Context* cpA, + const struct bbf_LocalScanner* ptrA, + const struct bbf_LocalScanner* srcPtrA ) +{ + bbs_ERROR0( "bbf_LocalScanner_equal:\n Function is not available" ); + return FALSE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanner_positions( const struct bbf_LocalScanner* ptrA ) +{ + int32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE; + int32 hL = ptrA->workScanRegionE.y2E - ptrA->workScanRegionE.y1E - ptrA->patchHeightE; + return ( ( wL < 0 ) ? 0 : wL ) * ( ( hL < 0 ) ? 0 : hL ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanner_scanIndex( const struct bbf_LocalScanner* ptrA ) +{ + int32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE; + return ( ptrA->yE - ptrA->workScanRegionE.y1E ) * wL + ( ptrA->xE - ptrA->workScanRegionE.x1E ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_pos( const struct bbf_LocalScanner* ptrA, int32* xPtrA, int32* yPtrA ) +{ + *xPtrA = ( ( ptrA->xE << ptrA->scaleExpE ) + ptrA->xOffE ) << 16; + *yPtrA = ( ( ptrA->yE << ptrA->scaleExpE ) + ptrA->yOffE ) << 16; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_idxPos( const struct bbf_LocalScanner* ptrA, uint32 scanIndexA, int32* xPtrA, int32* yPtrA ) +{ + uint32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE; + int32 xL = ( scanIndexA % wL ) + ptrA->workScanRegionE.x1E; + int32 yL = ( scanIndexA / wL ) + ptrA->workScanRegionE.y1E; + *xPtrA = ( ( xL << ptrA->scaleExpE ) + ptrA->xOffE ) << 16; + *yPtrA = ( ( yL << ptrA->scaleExpE ) + ptrA->yOffE ) << 16; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_create( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + uint32 patchWidthA, + uint32 patchHeightA, + uint32 scaleExpA, + uint32 maxImageWidthA, + uint32 maxImageHeightA, + uint32 minScaleExpA, + uint32 maxRadiusA, + struct bbs_MemTbl* mtpA ) +{ + ptrA->patchWidthE = patchWidthA; + ptrA->patchHeightE = patchHeightA; + ptrA->scaleExpE = scaleExpA; + ptrA->maxImageWidthE = maxImageWidthA; + ptrA->maxImageHeightE = maxImageHeightA; + ptrA->minScaleExpE = minScaleExpA; + ptrA->maxRadiusE = maxRadiusA; + bbf_LocalScanner_alloc( cpA, ptrA, mtpA ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_bitParam( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const struct bbf_BitParam* bitParamPtrA ) +{ + if( !bbf_BitParam_equal( cpA, &ptrA->bitParamE, bitParamPtrA ) ) + { + bbf_BitParam_copy( cpA, &ptrA->bitParamE, bitParamPtrA ); + bbf_LocalScanner_createBitImage( cpA, ptrA ); + } + + bbf_LocalScanner_resetScan( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_origScanRegion( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const struct bts_Int16Rect* scanRegionPtrA ) +{ + ptrA->origScanRegionE = *scanRegionPtrA; + bbf_LocalScanner_setWorkScanRegion( cpA, ptrA ); + bbf_LocalScanner_resetScan( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanner_memSize( struct bbs_Context* cpA, + const struct bbf_LocalScanner* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbs_SIZEOF16( ptrA->patchWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->patchHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->scaleExpE ); + memSizeL += bbs_SIZEOF16( ptrA->maxImageWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->maxImageHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->minScaleExpE ); + memSizeL += bbs_SIZEOF16( ptrA->maxRadiusE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanner_memWrite( struct bbs_Context* cpA, + const struct bbf_LocalScanner* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_LocalScanner_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_LOCAL_SCANNER_VERSION, memPtrA ); + + memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->scaleExpE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxImageWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxImageHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->minScaleExpE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxRadiusE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_LocalScanner_memRead( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_LOCAL_SCANNER_VERSION, memPtrA ); + + memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->scaleExpE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxImageWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxImageHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->minScaleExpE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxRadiusE, memPtrA ); + + if( memSizeL != bbf_LocalScanner_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_LocalScanner_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + if( bbs_Context_error( cpA ) ) return 0; + + /* allocate arrays */ + bbf_LocalScanner_alloc( cpA, ptrA, mtpA ); + + if( bbs_Context_error( cpA ) ) return 0; + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_resetScan( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA ) +{ + ptrA->xE = ptrA->workScanRegionE.x1E; + ptrA->yE = ptrA->workScanRegionE.y1E; + bbf_LocalScanner_initPatchBuffer( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_assign( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const uint8* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bbf_BitParam* paramPtrA ) +{ + if( ptrA->scaleExpE == 0 ) + { + ptrA->workImagePtrE = imagePtrA; + ptrA->workWidthE = imageWidthA; + ptrA->workHeightE = imageHeightA; + } + else + { + ptrA->origImagePtrE = imagePtrA; + ptrA->origWidthE = imageWidthA; + ptrA->origHeightE = imageHeightA; + } + + ptrA->bitParamE = *paramPtrA; + ptrA->xOffE = 0; + ptrA->yOffE = 0; + ptrA->origScanRegionE = bts_Int16Rect_create( 0, 0, imageWidthA, imageHeightA ); + bbf_LocalScanner_downscale( cpA, ptrA ); + bbf_LocalScanner_createBitImage( cpA, ptrA ); + bbf_LocalScanner_resetScan( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +const uint32* bbf_LocalScanner_getPatch( const struct bbf_LocalScanner* ptrA ) +{ + return ptrA->patchBufferE.arrPtrE + ptrA->xE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_LocalScanner_next( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + if( ( ptrA->xE + 1 ) < ptrA->workScanRegionE.x2E - ( int32 )ptrA->patchWidthE ) + { + ptrA->xE++; + return TRUE; + } + + if( ( ptrA->yE + 1 ) >= ptrA->workScanRegionE.y2E - ( int32 )ptrA->patchHeightE ) return FALSE; + + ptrA->xE = ptrA->workScanRegionE.x1E; + ptrA->yE++; + + { + uint32 offL = ( ptrA->yE & 0x1F ); + uint32 rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 ); + + uint32 widthL = ptrA->bitImageE.widthE; + uint32 sizeL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E; + uint32* dstL = ( uint32* )ptrA->patchBufferE.arrPtrE + ptrA->xE; + uint32 iL; + + if( rowL < ptrA->bitImageE.heightE ) + { + uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + rowL * widthL + ptrA->xE; + if( offL > 0 ) + { + uint32 shlL = 32 - offL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( dstL[ iL ] >> 1 ) | ( srcL[ iL ] << shlL ); + } + else + { + bbs_memcpy32( dstL, srcL, sizeL ); + } + } + else + { + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] >>= 1; + } + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_goToXY( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, int32 xA, int32 yA ) +{ + bbs_DEF_fNameL( "void bbf_LocalScanner_goToXY( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, int32 xA, int32 yA )" ) + if( xA < ptrA->workScanRegionE.x1E || xA >= ptrA->workScanRegionE.x2E - ( int32 )ptrA->patchWidthE ) + { + bbs_ERROR1( "%s:\nxA out of range", fNameL ); + return; + } + ptrA->xE = xA; + if( ptrA->yE == yA ) return; + if( yA < ptrA->workScanRegionE.y1E || yA >= ptrA->workScanRegionE.y2E - ( int32 )ptrA->patchHeightE ) + { + bbs_ERROR1( "%s:\nyA out of range", fNameL ); + return; + } + ptrA->yE = yA; + + { + uint32 offL = ( ptrA->yE & 0x1F ); + uint32 rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 ); + + uint32 sizeL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E; + uint32 imgWidthL = ptrA->bitImageE.widthE; + uint32 imgOffsL = ptrA->workScanRegionE.x1E; + uint32* dstL = ptrA->patchBufferE.arrPtrE + imgOffsL; + uint32 iL; + + if( rowL < ptrA->bitImageE.heightE ) + { + if( offL > 0 ) + { + uint32* src1L = ptrA->bitImageE.arrE.arrPtrE + rowL * imgWidthL + imgOffsL; + uint32* src0L = src1L - imgWidthL; + uint32 shlL = 32 - offL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( src0L[ iL ] >> offL ) | ( src1L[ iL ] << shlL ); + } + else + { + bbs_memcpy32( dstL, ptrA->bitImageE.arrE.arrPtrE + rowL * imgWidthL + imgOffsL, sizeL ); + } + } + else + { + uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + ( rowL - 1 ) * imgWidthL + imgOffsL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = srcL[ iL ] >> offL; + } + } +} + +/* ------------------------------------------------------------------------- */ + +void bbf_LocalScanner_goToIndex( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, uint32 scanIndexA ) +{ + uint32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE; + bbf_LocalScanner_goToXY( cpA, ptrA, + ( scanIndexA % wL ) + ptrA->workScanRegionE.x1E, + ( scanIndexA / wL ) + ptrA->workScanRegionE.y1E ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_LocalScanner_nextOffset( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ) +{ + int32 maxL = ( 1 << ptrA->scaleExpE ); + if( ptrA->yOffE == maxL ) return FALSE; + + ptrA->xOffE++; + + if( ptrA->xOffE == maxL ) + { + ptrA->xOffE = 0; + ptrA->yOffE++; + if( ptrA->yOffE == maxL ) return FALSE; + } + + bbf_LocalScanner_downscale( cpA, ptrA ); + bbf_LocalScanner_createBitImage( cpA, ptrA ); + bbf_LocalScanner_setWorkScanRegion( cpA, ptrA ); + bbf_LocalScanner_resetScan( cpA, ptrA ); + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_BitFeatureEm/LocalScanner.h b/Embedded/common/src/b_BitFeatureEm/LocalScanner.h new file mode 100644 index 0000000..36665b9 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/LocalScanner.h @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_LOCAL_SCANNER_EM_H +#define bbf_LOCAL_SCANNER_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BasicEm/UInt16Arr.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_ImageEm/UInt32Image.h" + +#include "b_BitFeatureEm/Feature.h" +#include "b_BitFeatureEm/BitParam.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_LOCAL_SCANNER_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** supports scanning an image on a fixed scale and provides patches on local areas as needed */ +struct bbf_LocalScanner +{ + /* ---- private data --------------------------------------------------- */ + + /** current scan x-coordinate */ + int32 xE; + + /** current scan y-coordinate */ + int32 yE; + + /** current xOffset */ + int32 xOffE; + + /** current yOffset */ + int32 yOffE; + + /** width of scaled image */ + uint32 currentWidthE; + + /** height of scaled image */ + uint32 currentHeightE; + + /** width of work image */ + uint32 workWidthE; + + /** height of work image */ + uint32 workHeightE; + + /** pointer to working image data */ + const uint8* workImagePtrE; + + /** width of original image */ + uint32 origWidthE; + + /** height of original image */ + uint32 origHeightE; + + /** pointer to original image data */ + const uint8* origImagePtrE; + + /** parameter for bit generation */ + struct bbf_BitParam bitParamE; + + /** work image (two pixels per uint16)*/ + struct bbs_UInt8Arr workImageBufferE; + + /** summed-area table (ring buffer) */ + struct bim_UInt32Image satE; + + /** bit image */ + struct bim_UInt32Image bitImageE; + + /** patch buffer */ + struct bbs_UInt32Arr patchBufferE; + + /** original scan region */ + struct bts_Int16Rect origScanRegionE; + + /** current scan region */ + struct bts_Int16Rect workScanRegionE; + + /* ---- public data ---------------------------------------------------- */ + + /** patch width */ + uint32 patchWidthE; + + /** patch height */ + uint32 patchHeightE; + + /** scale exponent (determines at which scale patch data is actually generated) */ + uint32 scaleExpE; + + /** max image width */ + uint32 maxImageWidthE; + + /** max image height */ + uint32 maxImageHeightE; + + /** min scale exponent */ + uint32 minScaleExpE; + + /** maximum filter radius */ + uint32 maxRadiusE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_LocalScanner */ +void bbf_LocalScanner_init( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA ); + +/** resets bbf_LocalScanner */ +void bbf_LocalScanner_exit( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_LocalScanner_copy( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const struct bbf_LocalScanner* srcPtrA ); + +/** equal operator */ +flag bbf_LocalScanner_equal( struct bbs_Context* cpA, + const struct bbf_LocalScanner* ptrA, + const struct bbf_LocalScanner* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** total scan positions at current scale */ +uint32 bbf_LocalScanner_positions( const struct bbf_LocalScanner* ptrA ); + +/** current scan index */ +uint32 bbf_LocalScanner_scanIndex( const struct bbf_LocalScanner* ptrA ); + +/** returns ul position relative to original image; x,y coordinates: 16.16 */ +void bbf_LocalScanner_pos( const struct bbf_LocalScanner* ptrA, int32* xPtrA, int32* yPtrA ); + +/** returns uls position relative to original image at index position; x,y coordinates: 16.16 */ +void bbf_LocalScanner_idxPos( const struct bbf_LocalScanner* ptrA, uint32 scanIndexA, int32* xPtrA, int32* yPtrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** creates & initializes object */ +void bbf_LocalScanner_create( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + uint32 patchWidthA, + uint32 patchHeightA, + uint32 scaleExpA, + uint32 maxImageWidthA, + uint32 maxImageHeightA, + uint32 minScaleExpA, + uint32 maxRadiusA, + struct bbs_MemTbl* mtpA ); + +/** parameter for bit generation + recomputing bit image */ +void bbf_LocalScanner_bitParam( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const struct bbf_BitParam* bitParamPtrA ); + +/** Specifies a (sub-) scan region + * Scanning within a given scale is limited to that region. + * Region is truncateed to physical region + * Image assignment, bitParam assignment and function nextScale reset the sacn region to + * the whole image. + */ +void bbf_LocalScanner_origScanRegion( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const struct bts_Int16Rect* scanRegionPtrA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_LocalScanner_memSize( struct bbs_Context* cpA, + const struct bbf_LocalScanner* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_LocalScanner_memWrite( struct bbs_Context* cpA, + const struct bbf_LocalScanner* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_LocalScanner_memRead( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** resets scan position at current scale level */ +void bbf_LocalScanner_resetScan( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA ); + +/** assigns image; sets initial bit parameters; resets processor */ +void bbf_LocalScanner_assign( struct bbs_Context* cpA, + struct bbf_LocalScanner* ptrA, + const uint8* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bbf_BitParam* paramPtrA ); + +/** returns pointer to patch data */ +const uint32* bbf_LocalScanner_getPatch( const struct bbf_LocalScanner* ptrA ); + +/** goes to next scan position */ +flag bbf_LocalScanner_next( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ); + +/** goes to scan position (integer coordinate numbers) */ +void bbf_LocalScanner_goToXY( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, int32 xA, int32 yA ); + +/** goes to scan position */ +void bbf_LocalScanner_goToIndex( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, uint32 scanIndexA ); + +/** goes to next offset position */ +flag bbf_LocalScanner_nextOffset( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA ); + +#endif /* bbf_LOCAL_SCANNER_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/ScanDetector.c b/Embedded/common/src/b_BitFeatureEm/ScanDetector.c new file mode 100644 index 0000000..44b48bf --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/ScanDetector.c @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/ScanDetector.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_ScanDetector_init( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA ) +{ + uint32 iL; + + ptrA->minScaleE = 0; + ptrA->maxScaleE = 0; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + bbf_Scanner_init( cpA, &ptrA->scannerE ); + + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->minDefScaleE = 0; + ptrA->maxDefScaleE = 0; + ptrA->scaleStepE = 0; + ptrA->overlapThrE = 0; + ptrA->borderWidthE = 0; + ptrA->borderHeightE = 0; + ptrA->featuresE = 0; + for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_BitParam_init( cpA, &ptrA->bitParamArrE[ iL ] ); + for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_Sequence_init( cpA, &ptrA->featureArrE[ iL ] ); + bts_IdCluster2D_init( cpA, &ptrA->refClusterE ); + ptrA->refDistanceE = 10; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_ScanDetector_exit( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA ) +{ + uint32 iL; + + ptrA->minScaleE = 0; + ptrA->maxScaleE = 0; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + bbf_Scanner_exit( cpA, &ptrA->scannerE ); + + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->minDefScaleE = 0; + ptrA->maxDefScaleE = 0; + ptrA->scaleStepE = 0; + ptrA->overlapThrE = 0; + ptrA->borderWidthE = 0; + ptrA->borderHeightE = 0; + ptrA->featuresE = 0; + for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_BitParam_exit( cpA, &ptrA->bitParamArrE[ iL ] ); + for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_Sequence_exit( cpA, &ptrA->featureArrE[ iL ] ); + bts_IdCluster2D_exit( cpA, &ptrA->refClusterE ); + ptrA->refDistanceE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_ScanDetector_copy( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA, + const struct bbf_ScanDetector* srcPtrA ) +{ + bbs_ERROR0( "bbf_ScanDetector_copy:\n Function is not available" ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_ScanDetector_equal( struct bbs_Context* cpA, + const struct bbf_ScanDetector* ptrA, + const struct bbf_ScanDetector* srcPtrA ) +{ + bbs_ERROR0( "bbf_ScanDetector_equal:\n Function is not available" ); + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_ScanDetector_memSize( struct bbs_Context* cpA, + const struct bbf_ScanDetector* ptrA ) +{ + uint32 iL; + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbs_SIZEOF16( ptrA->patchWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->patchHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->minDefScaleE ); + memSizeL += bbs_SIZEOF16( ptrA->maxDefScaleE ); + memSizeL += bbs_SIZEOF16( ptrA->scaleStepE ); + memSizeL += bbs_SIZEOF16( ptrA->overlapThrE ); + memSizeL += bbs_SIZEOF16( ptrA->borderWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->borderHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->featuresE ); + for( iL = 0; iL < ptrA->featuresE; iL++ ) memSizeL += bbf_BitParam_memSize( cpA, &ptrA->bitParamArrE[ iL ] ); + for( iL = 0; iL < ptrA->featuresE; iL++ ) memSizeL += bbf_Sequence_memSize( cpA, &ptrA->featureArrE[ iL ] ); + memSizeL += bts_IdCluster2D_memSize( cpA, &ptrA->refClusterE ); + memSizeL += bbs_SIZEOF16( ptrA->refDistanceE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_ScanDetector_memWrite( struct bbs_Context* cpA, + const struct bbf_ScanDetector* ptrA, + uint16* memPtrA ) +{ + uint32 iL; + uint32 memSizeL = bbf_ScanDetector_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_SCAN_DETECTOR_VERSION, memPtrA ); + + memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->minDefScaleE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxDefScaleE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->scaleStepE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->overlapThrE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->borderWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->borderHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->featuresE, memPtrA ); + for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_BitParam_memWrite( cpA, &ptrA->bitParamArrE[ iL ], memPtrA ); + for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_Sequence_memWrite( cpA, &ptrA->featureArrE[ iL ], memPtrA ); + memPtrA += bts_IdCluster2D_memWrite( cpA, &ptrA->refClusterE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->refDistanceE, memPtrA ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_ScanDetector_memRead( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + bbs_DEF_fNameL( "bbf_ScanDetector_memRead" ) + + /* debugging hint: set this flag to FALSE when you suspect a shared memory conflict */ + const flag maximizeSharedMemoryL = TRUE; + + uint32 iL; + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_SCAN_DETECTOR_VERSION, memPtrA ); + + memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->minDefScaleE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxDefScaleE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->scaleStepE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->overlapThrE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->borderWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->borderHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->featuresE, memPtrA ); + for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_BitParam_memRead( cpA, &ptrA->bitParamArrE[ iL ], memPtrA ); + for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_Sequence_memRead( cpA, &ptrA->featureArrE[ iL ], memPtrA, &memTblL ); + memPtrA += bts_IdCluster2D_memRead( cpA, &ptrA->refClusterE, memPtrA, espL ); + memPtrA += bbs_memRead32( &ptrA->refDistanceE, memPtrA ); +/* + if( memSizeL != bbf_ScanDetector_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_ScanDetector_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } +*/ + + ptrA->minScaleE = ptrA->minDefScaleE; + ptrA->maxScaleE = ptrA->maxDefScaleE; + + /* initialize scanner; be aware of shared memory settings(!) */ + { + uint32 maxImageSizeL = ptrA->maxImageWidthE * ptrA->maxImageHeightE; + + /* estimate of maximal possible faces in image */ + uint32 maxFacesL = maxImageSizeL / ( 768 << 1 ); + + uint32 maxRadiusL = 0; + + if( maxImageSizeL == 0 ) + { + bbs_ERROR1( "%s:\nMaximum image size was not defined (size variables must be set before calling _memRead)", fNameL ); + return memSizeL; + } + + for( iL = 0; iL < ptrA->featuresE; iL++ ) + { + maxRadiusL = maxRadiusL > ptrA->bitParamArrE[ iL ].outerRadiusE ? maxRadiusL : ptrA->bitParamArrE[ iL ].outerRadiusE; + } + + if( maxFacesL < 1 ) maxFacesL = 1; + + bbf_Scanner_create( cpA, &ptrA->scannerE, + maximizeSharedMemoryL, + ptrA->maxImageWidthE, + ptrA->maxImageHeightE, + maxRadiusL, + ptrA->patchWidthE, + ptrA->patchHeightE, + ptrA->minScaleE, + ptrA->maxScaleE, + ptrA->scaleStepE, + ptrA->borderWidthE, + ptrA->borderHeightE, + maxFacesL * 20, /* bufferSizeA */ + &memTblL ); + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_ScanDetector_process( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA, + const void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA, + int32** outArrPtrPtrA ) +{ + /* best global values (used when no positives could be found) */ + int32 bestGlobalActL = ( int32 )0x80000000; + int32 bestGlobalXL = 0; + int32 bestGlobalYL = 0; + uint32 bestGlobalScaleL = 0; + + struct bbf_Scanner* scannerPtrL = &ptrA->scannerE; + + scannerPtrL->minScaleE = ptrA->minScaleE; + scannerPtrL->maxScaleE = ptrA->maxScaleE; + + *outArrPtrPtrA = NULL; + + if( bbs_Context_error( cpA ) ) return 0; + if( ptrA->featuresE == 0 ) + { + bbs_ERROR0( "bbf_ScanDetector_process: detector has no features" ); + return 0; + } + + if( imageWidthA > ptrA->maxImageWidthE || imageHeightA > ptrA->maxImageHeightE ) + { + bbs_ERROR0( "bbf_ScanDetector_process: images size exceeds preallocated size" ); + return 0; + } + + /* resets output positions */ + bbf_Scanner_resetOutPos( cpA, scannerPtrL ); + + /* assign image to scanner - reset scanner */ + bbf_Scanner_assign( cpA, scannerPtrL, imagePtrA, imageWidthA, imageHeightA, roiPtrA, &ptrA->bitParamArrE[ 0 ] ); + + while( bbf_Scanner_positions( scannerPtrL ) > 0 ) + { + int32 bestActL = ( int32 )0x80000000; + uint32 bestIdxL = 0; + uint32 bestLvlL = 0; + uint32 iL; + + const struct bbf_Feature* featurePtrL = ( const struct bbf_Feature* )&ptrA->featureArrE[ 0 ]; + const struct bbf_BitParam* paramPtrL = &ptrA->bitParamArrE[ 0 ]; + bbf_Scanner_bitParam( cpA, scannerPtrL, paramPtrL ); + + /* resets internal positions */ + bbf_Scanner_resetIntPos( cpA, scannerPtrL ); + + do + { + int32 actL = featurePtrL->vpActivityE( featurePtrL, bbf_Scanner_getPatch( scannerPtrL ) ); + if( actL > 0 ) + { + bbf_Scanner_addIntPos( cpA, scannerPtrL, bbf_Scanner_scanIndex( scannerPtrL ), actL ); + } + + if( actL > bestActL ) + { + bestActL = actL; + bestIdxL = bbf_Scanner_scanIndex( scannerPtrL ); + } + } + while( bbf_Scanner_next( cpA, scannerPtrL ) ); + + for( iL = 1; iL < ptrA->featuresE; iL++ ) + { + const struct bbf_Feature* featurePtrL = ( const struct bbf_Feature* )&ptrA->featureArrE[ iL ]; + const struct bbf_BitParam* paramPtrL = &ptrA->bitParamArrE[ iL ]; + uint32* idxArrL = scannerPtrL->idxArrE.arrPtrE; + int32* actArrL = scannerPtrL->actArrE.arrPtrE; + + uint32 kL = 0; + uint32 jL; + + if( scannerPtrL->intCountE == 0 ) break; + bestActL = ( int32 )0x80000000; + bbf_Scanner_bitParam( cpA, scannerPtrL, paramPtrL ); + + for( jL = 0; jL < scannerPtrL->intCountE; jL++ ) + { + int32 actL; + bbf_Scanner_goToIndex( cpA, scannerPtrL, idxArrL[ jL ] ); + actL = featurePtrL->vpActivityE( featurePtrL, bbf_Scanner_getPatch( scannerPtrL ) ); + if( actL > 0 ) + { + idxArrL[ kL ] = idxArrL[ jL ]; + actArrL[ kL ] = ( actArrL[ jL ] + actL ) >> 1; + kL++; + } + + if( actL > bestActL ) + { + bestActL = actL; + bestIdxL = idxArrL[ jL ]; + bestLvlL = iL; + } + } + + scannerPtrL->intCountE = kL; + } + + if( scannerPtrL->intCountE == 0 ) + { + int32 xL, yL; + uint32 scaleL; + + /* 8.24 */ + int32 actL = ( bestActL >> 4 ) + ( ( ( int32 )( bestLvlL + 1 - ptrA->featuresE ) << 24 ) / ( int32 )ptrA->featuresE ); + + /* 4.28 */ + actL <<= 4; + + bbf_Scanner_idxPos( scannerPtrL, bestIdxL, &xL, &yL, &scaleL ); + + if( actL > bestGlobalActL ) + { + bestGlobalActL = actL; + bestGlobalXL = xL; + bestGlobalYL = yL; + bestGlobalScaleL = scaleL; + } + } + else + { + /* remove overlaps for current scale */ + bbf_Scanner_removeIntOverlaps( cpA, scannerPtrL, ptrA->overlapThrE ); + + for( iL = 0; iL < scannerPtrL->intCountE; iL++ ) + { + int32 xL, yL; + uint32 scaleL; + uint32* idxArrL = scannerPtrL->idxArrE.arrPtrE; + int32* actArrL = scannerPtrL->actArrE.arrPtrE; + + int32 actL = actArrL[ iL ]; + bbf_Scanner_idxPos( scannerPtrL, idxArrL[ iL ], &xL, &yL, &scaleL ); + + /* add external position */ + bbf_Scanner_addOutPos( cpA, scannerPtrL, xL, yL, scaleL, actL ); + } + + /* remove overlapping positions */ + bbf_Scanner_removeOutOverlaps( cpA, scannerPtrL, ptrA->overlapThrE ); + + } + + if( !bbf_Scanner_nextScale( cpA, scannerPtrL ) ) break; + } +/* + { + uint32 iL; + printf( "\n-----------------------------------------------" ); + for( iL = 0; iL < scannerPtrL->outCountE; iL++ ) + { + printf( "\n%02i: %6.1f %6.1f %6.2f %6.3f", + iL, + ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 0 ] / ( 1L << 16 ), + ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 1 ] / ( 1L << 16 ), + ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 2 ] / ( 1L << 20 ), + ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 3 ] / ( 1L << 28 ) ); + + } + } +*/ + + *outArrPtrPtrA = scannerPtrL->outArrE.arrPtrE; + if( scannerPtrL->outCountE == 0 ) + { + /* no positive activities found: store best negative activity */ + bbf_Scanner_addOutPos( cpA, scannerPtrL, bestGlobalXL, bestGlobalYL, bestGlobalScaleL, bestGlobalActL ); + return 0; + } + else + { + return scannerPtrL->outCountE; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/ScanDetector.h b/Embedded/common/src/b_BitFeatureEm/ScanDetector.h new file mode 100644 index 0000000..7d44f81 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/ScanDetector.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_SCAN_DETECTOR_EM_H +#define bbf_SCAN_DETECTOR_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/IdCluster2D.h" +#include "b_BitFeatureEm/Sequence.h" +#include "b_BitFeatureEm/BitParam.h" +#include "b_BitFeatureEm/Scanner.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_SCAN_DETECTOR_VERSION 100 + +/* maximum number of features in scan detector */ +#define bbf_SCAN_DETECTOR_MAX_FEATURES 4 + +/* ---- object definition -------------------------------------------------- */ + +/** discrete feature set */ +struct bbf_ScanDetector +{ + /* ---- private data --------------------------------------------------- */ + + /** minimum scale (12.20) */ + uint32 minScaleE; + + /** maximum scale (0: unlimited) (12.20) */ + uint32 maxScaleE; + + /** maximum image width (this variable must be specified before reading the parameter file) */ + uint32 maxImageWidthE; + + /** maximum image height (this variable must be specified before reading the parameter file) */ + uint32 maxImageHeightE; + + /** scanner */ + struct bbf_Scanner scannerE; + + /* ---- public data ---------------------------------------------------- */ + + /** patch width */ + uint32 patchWidthE; + + /** patch height */ + uint32 patchHeightE; + + /** minimum default scale (12.20) */ + uint32 minDefScaleE; + + /** maximum default scale (0: unlimited) (12.20) */ + uint32 maxDefScaleE; + + /** scale step factor (1.32) (leading bit is always one and therefore ignored) */ + uint32 scaleStepE; + + /** overlap threshold (16.16) */ + uint32 overlapThrE; + + /** border width in pixels (refers to scaled image) */ + uint32 borderWidthE; + + /** border height in pixels (refers to scaled image) */ + uint32 borderHeightE; + + /** number of features */ + uint32 featuresE; + + /** bit param array */ + struct bbf_BitParam bitParamArrE[ bbf_SCAN_DETECTOR_MAX_FEATURES ]; + + /** feature array */ + struct bbf_Sequence featureArrE[ bbf_SCAN_DETECTOR_MAX_FEATURES ]; + + /** reference cluster */ + struct bts_IdCluster2D refClusterE; + + /** reference distance (e.g. eye distance) in ref cluster (16.16) */ + uint32 refDistanceE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_ScanDetector */ +void bbf_ScanDetector_init( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA ); + +/** resets bbf_ScanDetector */ +void bbf_ScanDetector_exit( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_ScanDetector_copy( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA, + const struct bbf_ScanDetector* srcPtrA ); + +/** equal operator */ +flag bbf_ScanDetector_equal( struct bbs_Context* cpA, + const struct bbf_ScanDetector* ptrA, + const struct bbf_ScanDetector* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_ScanDetector_memSize( struct bbs_Context* cpA, + const struct bbf_ScanDetector* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_ScanDetector_memWrite( struct bbs_Context* cpA, + const struct bbf_ScanDetector* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_ScanDetector_memRead( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Scans over image returns number of detected positions + * After processing the output data are stored in composite format + * in scannerPtrA->outArrE. + * + * The output data array is located after execution at *outArrPtrPtrA. + * The output data are organized as follows: + * x(16.16) y(16.16), scale(12.20), confidence(4.28), x(16.16).... + * + * All positions are sorted by descending confidence + * + * If no faces were found, the function returns 0 but the output contains + * one valid position with the highest confidence; the associated activity + * value is negative (or 0) in that case. + * + * If roiPtrA is NULL, the whole image is considered for processsing + * otherwise *roiPtrA specifies a section of the original image to which + * processing is limited. All coordinates refer to that section and must + * eventually be adjusted externally. + * The roi rectangle must not include pixels outside of the original image + * (checked -> error). The rectangle may be of uneven width. + */ +uint32 bbf_ScanDetector_process( struct bbs_Context* cpA, + struct bbf_ScanDetector* ptrA, + const void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA, + int32** outArrPtrPtrA ); + +#endif /* bbf_SCAN_DETECTOR_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Scanner.c b/Embedded/common/src/b_BitFeatureEm/Scanner.c new file mode 100644 index 0000000..327e714 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Scanner.c @@ -0,0 +1,1290 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/Scanner.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/** multiplies a scale with a 0.32 scale factor */ +uint32 bbf_Scanner_scalePrd( uint32 scaleA, uint32 factorA /*0.32 */ )\ +{ + return ( scaleA >> 16 ) * ( factorA >> 16 ) + + ( ( ( scaleA & 0x0FFFF ) * ( factorA >> 16 ) ) >> 16 ) + + ( ( ( scaleA >> 16 ) * ( factorA & 0x0FFFF ) ) >> 16 ); +} + +/* ------------------------------------------------------------------------- */ + +/** allocates arays */ +void bbf_Scanner_alloc( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + struct bbs_MemTbl* mtpA, + flag maximizeSharedMemoryA ) +{ + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + struct bbs_MemSeg* sspL = bbs_MemTbl_sharedSegPtr( cpA, &memTblL, 0 ); + struct bbs_MemSeg* mspL = maximizeSharedMemoryA ? sspL : espL; + + /* filter patch dimension */ + uint32 proL = ptrA->maxRadiusE; + uint32 pwoL = ( proL << 1 ) + 1; + + /* output image size (bit image) */ + uint32 woL = ptrA->maxImageWidthE; + uint32 hoL = ptrA->maxImageHeightE; + + /* extended output image size (bit image) considering borders */ + uint32 xwoL = woL + ( ptrA->borderWidthE << 1 ); + uint32 xhoL = hoL + ( ptrA->borderHeightE << 1 ); + + /* allocate working image */ + bbs_UInt16Arr_create( cpA, &ptrA->workImageE, ( ( woL >> 1 ) + ( woL & 1 ) ) * hoL, mspL ); + if( bbs_Context_error( cpA ) ) return; + bbs_UInt16Arr_fill( cpA, &ptrA->workImageE, 0 ); + + /* allocate bit image */ + bim_UInt32Image_create( cpA, &ptrA->bitImageE, xwoL, ( xhoL >> 5 ) + ( ( ( xhoL & 0x1F ) != 0 ) ? 1 : 0 ), mspL ); + if( bbs_Context_error( cpA ) ) return; + bim_UInt32Image_setAllPixels( cpA, &ptrA->bitImageE, 0, 0 ); + + /* allocate patch buffer */ + bbs_UInt32Arr_create( cpA, &ptrA->patchBufferE, ptrA->bitImageE.widthE, mspL ); + if( bbs_Context_error( cpA ) ) return; + bbs_UInt32Arr_fill( cpA, &ptrA->patchBufferE, 0 ); + + /* allocate line buffer */ + bbs_UInt16Arr_create( cpA, &ptrA->lineBufE, woL + ( woL & 1 ), sspL ); + + /* allocate table */ + bim_UInt32Image_create( cpA, &ptrA->satE, woL + pwoL, pwoL + 1, sspL ); + + /* allocate buffers */ + bbs_UInt32Arr_create( cpA, &ptrA->idxArrE, ptrA->bufferSizeE, mspL ); + bbs_Int32Arr_create( cpA, &ptrA->actArrE, ptrA->bufferSizeE, mspL ); + + bbs_Int32Arr_create( cpA, &ptrA->outArrE, ptrA->bufferSizeE >> 1, espL ); +} + +/* ------------------------------------------------------------------------- */ + +/** downscales work image */ +void bbf_Scanner_downscale( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + uint32 w0L = ptrA->workWidthE; + uint32 h0L = ptrA->workHeightE; + uint32 w1L = w0L >> 1; + uint32 h1L = h0L >> 1; + uint32 w20L = ( w0L >> 1 ) + ( w0L & 1 ); + uint16* arrL = ptrA->workImageE.arrPtrE; + + uint32 iL, jL; + uint32 kL = 0; + for( jL = 0; jL < h1L; jL++ ) + { + for( iL = 0; iL < ( w1L >> 1 ); iL++ ) + { + uint16 loL, hiL; + uint32 idxL = jL * 2 * w20L + iL * 2; + + loL = ( ( arrL[ idxL ] & 0x00FF ) + ( arrL[ idxL ] >> 8 ) + ( arrL[ idxL + w20L ] & 0x00FF ) + ( arrL[ idxL + w20L ] >> 8 ) + 2 ) >> 2; + idxL++; + hiL = ( ( arrL[ idxL ] & 0x00FF ) + ( arrL[ idxL ] >> 8 ) + ( arrL[ idxL + w20L ] & 0x00FF ) + ( arrL[ idxL + w20L ] >> 8 ) + 2 ) >> 2; + + arrL[ kL ] = loL | ( hiL << 8 ); + kL++; + } + if( ( w1L & 1 ) != 0 ) + { + uint32 idxL = jL * 2 * w20L + iL; + arrL[ kL++ ] = ( ( arrL[ idxL ] & 0x00FF ) + ( arrL[ idxL ] >> 8 ) + ( arrL[ idxL + w20L ] & 0x00FF ) + ( arrL[ idxL + w20L ] >> 8 ) + 2 ) >> 2; + } + } + + ptrA->workWidthE = w1L; + ptrA->workHeightE = h1L; + ptrA->scaleExpE++; +} + +/* ------------------------------------------------------------------------- */ + +/** copies image + * handling for 8 bit images is implemented + * 16 bit image handling for the whole class needs to be added in this function only + */ +void bbf_Scanner_copyImage( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, const void* imagePtrA, uint32 imageWidthA, uint32 imageHeightA, const struct bts_Int16Rect* roiPtrA ) +{ + bbs_DEF_fNameL( "void bbf_Scanner_copyImage( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, const struct bim_UInt16ByteImage* imagePtrA, const struct bts_Int16Rect* roiPtrA )" ) + + if( imageWidthA > ptrA->maxImageWidthE || imageHeightA > ptrA->maxImageHeightE ) + { + bbs_ERROR5( "%s:\n Input image (%ix%i)is too large; Scanner is configured for maximal (%ix%i)", + fNameL, imageWidthA, imageHeightA, ptrA->maxImageWidthE, ptrA->maxImageHeightE ); + return; + } + + if( roiPtrA == 0 ) + { + uint32 iL, jL; + const uint8* srcL = ( uint8* )imagePtrA; + uint16* dstL = ptrA->workImageE.arrPtrE; + ptrA->workWidthE = imageWidthA; + ptrA->workHeightE = imageHeightA; + for( iL = 0; iL < ptrA->workHeightE; iL++ ) + { + for( jL = ptrA->workWidthE >> 1; jL > 0; jL-- ) + { + *dstL++ = ( uint16 )srcL[ 0 ] | ( uint16 )srcL[ 1 ] << 8; + srcL += 2; + } + + /* uneven width */ + if( ptrA->workWidthE & 1 ) *dstL++ = *srcL++; + } + } + else + { + uint32 iL, jL; + const uint8* srcL = ( uint8* )imagePtrA + roiPtrA->y1E * imageWidthA + roiPtrA->x1E; + uint16* dstL = ptrA->workImageE.arrPtrE; + + if( roiPtrA->x2E <= roiPtrA->x1E || roiPtrA->y2E <= roiPtrA->y1E ) + { + bbs_ERROR1( "%s:\n ROI is invalid or zero", fNameL ); + return; + } + if( roiPtrA->x1E < 0 || roiPtrA->y1E < 0 || roiPtrA->x2E > ( int32 )imageWidthA || roiPtrA->y2E > ( int32 )imageHeightA ) + { + bbs_ERROR1( "%s:\n ROI exceeds image boundary", fNameL ); + return; + } + + ptrA->workWidthE = roiPtrA->x2E - roiPtrA->x1E; + ptrA->workHeightE = roiPtrA->y2E - roiPtrA->y1E; + for( iL = 0; iL < ptrA->workHeightE; iL++ ) + { + for( jL = ptrA->workWidthE >> 1; jL > 0; jL-- ) + { + *dstL++ = ( uint16 )srcL[ 0 ] | ( uint16 )srcL[ 1 ] << 8; + srcL += 2; + } + + /* uneven width */ + if( ptrA->workWidthE & 1 ) *dstL++ = *srcL++; + + srcL += imageWidthA - ptrA->workWidthE; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/** creates bit image */ +void bbf_Scanner_createBitImage( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + bbs_DEF_fNameL( "void bbf_Scanner_createBitImage( struct bbs_Context* cpA, struct bbf_Scanner* ptrA )" ) + + + /* declarations */ + uint32 proL, priL, pwoL, pwiL; + uint32 wiL, wi2L, hiL, woL, hoL, xwoL, xhoL; /* image size specifies */ + uint32 stepL; /* scan step (16.16) */ + uint32 bitMaskL; /* current bit mask */ + uint32* bitRowL; /* pointer to bit-row */ + uint32 wsL, hsL; /* size of summed area table (ringbuffer) */ + uint32 satSizeL; + uint32* satL; /* pointer to summed area table */ + uint16* lBufL; /* pointer to line buffer */ + uint32 yfL; /* fixed point y-coordinate (16.16) */ + uint32 iL, jL; + + uint32 swi1L; /* table writing index */ + uint32 swi2L; /* table writing index */ + uint32 sriL; /* table reading index */ + + uint32 poAreaL, piAreaL; /* areas of inner and outer rectangles */ + uint32 siL[ 8 ]; /* table indices */ + + + proL = ptrA->bitParamE.outerRadiusE; + priL = ptrA->bitParamE.innerRadiusE; + pwoL = ( proL << 1 ) + 1; + pwiL = ( priL << 1 ) + 1; + + if( ptrA->borderHeightE >= 32 ) + { + bbs_ERROR1( "%s:\n borderHeightE >= 32", fNameL ); + return; + } + + if( proL <= priL ) + { + bbs_ERROR1( "%s:\n outer radius <= inner radius", fNameL ); + return; + } + + /* input image size (bit image) */ + wiL = ptrA->workWidthE; + hiL = ptrA->workHeightE; + wi2L = ( wiL >> 1 ) + ( wiL & 1 ); + + /* 16.16 */ + stepL = ptrA->scaleE >> ( ptrA->scaleExpE + 4 ); + + /* output image size (bit image) */ + woL = ( wiL << 16 ) / stepL; + hoL = ( hiL << 16 ) / stepL; + + if( woL <= pwoL || hoL <= pwoL ) + { + bbs_ERROR1( "%s:\n scaled image is too small", fNameL ); + return; + } + + if( woL * stepL >= ( wiL << 16 ) ) woL--; + if( hoL * stepL >= ( hiL << 16 ) ) hoL--; + + /* extended output image size (bit image) considering borders */ + xwoL = woL + ( ptrA->borderWidthE << 1 ); + xhoL = hoL + ( ptrA->borderHeightE << 1 ); + + ptrA->currentWidthE = xwoL; + ptrA->currentHeightE = xhoL; + + /* initialize bit image */ + bim_UInt32Image_size( cpA, &ptrA->bitImageE, xwoL, ( xhoL >> 5 ) + ( ( ( xhoL & 0x1F ) != 0 ) ? 1 : 0 ) ); + bim_UInt32Image_setAllPixels( cpA, &ptrA->bitImageE, 0, 0 ); + + bitMaskL = ( uint32 )1 << ptrA->borderHeightE; + bitRowL = ( uint32* )ptrA->bitImageE.arrE.arrPtrE + ptrA->borderWidthE; + + /* width of table */ + wsL = woL + pwoL; + + /* height of table */ + hsL = pwoL + 1; + + bim_UInt32Image_size( cpA, &ptrA->satE, wsL, hsL ); + + satL = ptrA->satE.arrE.arrPtrE; + satSizeL = wsL * hsL; + + lBufL = ptrA->lineBufE.arrPtrE; + + yfL = 0; /* fixed point y-coordinate ( 16.16 )*/ + + swi1L = 0; /* table writing index */ + swi2L = 0; /* table writing index */ + sriL = 0; /* table reading index */ + + /* areas of inner and outer rectangles */ + poAreaL = pwoL * pwoL; + piAreaL = pwiL * pwiL; + + /* interpolate pixels; compute table and bit image */ + + for( iL = wsL * ( proL + 1 ); iL > 0; iL-- ) satL[ swi1L++ ] = 0; + swi2L = swi1L - wsL; + + for( jL = 0; jL < hoL + proL; jL++ ) + { + if( jL < hoL ) /* rescale area */ + { + uint32 ypL = ( yfL >> 16 ); + uint32 yoff1L = yfL & 0x0FFFF; + uint32 yoff0L = 0x010000 - yoff1L; + const uint16* arr0L = ptrA->workImageE.arrPtrE + ypL * wi2L; + const uint16* arr1L = arr0L + wi2L; + + + uint32 xfL = 0; /* fixed point x-coordinate (16.16) */ + uint32 hSumL = 0; + + yfL += stepL; + + for( iL = 0; iL <= proL; iL++ ) satL[ swi1L++ ] = 0; + swi2L += iL; + + /* fill line buffer */ + for( iL = 0; iL < wi2L; iL++ ) + { + lBufL[ iL * 2 ] = ( ( ( arr0L[ iL ] & 0x0FF ) * yoff0L ) + ( ( arr1L[ iL ] & 0x0FF ) * yoff1L ) ) >> 10; + lBufL[ iL * 2 + 1 ] = ( ( ( arr0L[ iL ] >> 8 ) * yoff0L ) + ( ( arr1L[ iL ] >> 8 ) * yoff1L ) ) >> 10; + } + + for( iL = 0; iL < woL; iL++ ) + { + uint32 xpL = ( xfL >> 16 ); + uint32 xoff1L = xfL & 0x0FFFF; + uint16 pixL = ( lBufL[ xpL ] * ( 0x010000 - xoff1L ) + lBufL[ xpL + 1 ] * xoff1L ) >> 22; + satL[ swi1L ] = ( hSumL += pixL ) + satL[ swi2L ]; + xfL += stepL; + swi1L++; + swi2L++; + } + + for( iL = 0; iL < proL; iL++ ) + { + satL[ swi1L ] = hSumL + satL[ swi2L ]; + swi1L++; + swi2L++; + } + } + else /* image is processed - fill in 0s */ + { + for( iL = 0; iL < wsL; iL++ ) satL[ swi1L++ ] = satL[ swi2L++ ]; + } + + swi1L = ( swi1L < satSizeL ) ? swi1L : 0; + swi2L = ( swi2L < satSizeL ) ? swi2L : 0; + + /* fill line in bit image */ + if( jL >= proL ) + { + const uint32* rSatL = satL; + + /* table coordinate indices for outer rectangle */ + siL[ 0 ] = sriL; + siL[ 1 ] = siL[ 0 ] + pwoL; + siL[ 2 ] = siL[ 0 ] + pwoL * wsL; + siL[ 2 ] -= ( siL[ 2 ] >= satSizeL ) ? satSizeL : 0; + siL[ 3 ] = siL[ 2 ] + pwoL; + + /* table coordinate indices for inner rectangle */ + siL[ 4 ] = siL[ 0 ] + ( proL - priL ) * wsL + ( proL - priL ); + siL[ 4 ] -= ( siL[ 4 ] >= satSizeL ) ? satSizeL : 0; + siL[ 5 ] = siL[ 4 ] + pwiL; + siL[ 6 ] = siL[ 4 ] + pwiL * wsL; + siL[ 6 ] -= ( siL[ 6 ] >= satSizeL ) ? satSizeL : 0; + siL[ 7 ] = siL[ 6 ] + pwiL; + sriL += wsL; + if( sriL == satSizeL ) sriL = 0; + + for( iL = 0; iL < woL; iL++ ) + { + uint32 oAvgL = ( rSatL[ siL[ 0 ] ] - rSatL[ siL[ 1 ] ] - rSatL[ siL[ 2 ] ] + rSatL[ siL[ 3 ] ] ) * piAreaL; + uint32 iAvgL = ( rSatL[ siL[ 4 ] ] - rSatL[ siL[ 5 ] ] - rSatL[ siL[ 6 ] ] + rSatL[ siL[ 7 ] ] ) * poAreaL; + bitRowL[ iL ] |= ( iAvgL > oAvgL ) ? bitMaskL : 0; + rSatL++; + } + if( ( bitMaskL <<= 1 ) == 0 ) + { + bitRowL += xwoL; + bitMaskL = 1; + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +/** initialize patch buffer */ +void bbf_Scanner_initPatchBuffer( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + bbs_UInt32Arr_size( cpA, &ptrA->patchBufferE, ptrA->bitImageE.widthE ); + bbs_memcpy32( ptrA->patchBufferE.arrPtrE, ptrA->bitImageE.arrE.arrPtrE, ptrA->bitImageE.widthE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_init( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA ) +{ + ptrA->scaleExpE = 0; + ptrA->scaleE = 0; + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->effMaxScaleE = 0; + ptrA->currentWidthE = 0; + ptrA->currentHeightE = 0; + ptrA->workWidthE = 0; + ptrA->workHeightE = 0; + bbf_BitParam_init( cpA, &ptrA->bitParamE ); + bbs_UInt16Arr_init( cpA, &ptrA->workImageE ); + bim_UInt32Image_init( cpA, &ptrA->satE ); + bim_UInt32Image_init( cpA, &ptrA->bitImageE ); + bbs_UInt32Arr_init( cpA, &ptrA->patchBufferE ); + bbs_UInt16Arr_init( cpA, &ptrA->lineBufE ); + + bbs_UInt32Arr_init( cpA, &ptrA->idxArrE ); + bbs_Int32Arr_init( cpA, &ptrA->actArrE ); + bbs_Int32Arr_init( cpA, &ptrA->outArrE ); + ptrA->outCountE = 0; + ptrA->intCountE = 0; + ptrA->bufferSizeE = 1024; + + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + ptrA->maxRadiusE = 0; + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->minScaleE = 0; + ptrA->maxScaleE = 0; + ptrA->scaleStepE = 0; + ptrA->borderWidthE = 0; + ptrA->borderHeightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_exit( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA ) +{ + ptrA->scaleExpE = 0; + ptrA->scaleE = 0; + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->effMaxScaleE = 0; + ptrA->currentWidthE = 0; + ptrA->currentHeightE = 0; + ptrA->workWidthE = 0; + ptrA->workHeightE = 0; + bbf_BitParam_exit( cpA, &ptrA->bitParamE ); + bbs_UInt16Arr_exit( cpA, &ptrA->workImageE ); + bim_UInt32Image_exit( cpA, &ptrA->satE ); + bim_UInt32Image_exit( cpA, &ptrA->bitImageE ); + bbs_UInt32Arr_exit( cpA, &ptrA->patchBufferE ); + bbs_UInt16Arr_exit( cpA, &ptrA->lineBufE ); + + bbs_UInt32Arr_exit( cpA, &ptrA->idxArrE ); + bbs_Int32Arr_exit( cpA, &ptrA->actArrE ); + bbs_Int32Arr_exit( cpA, &ptrA->outArrE ); + ptrA->outCountE = 0; + ptrA->intCountE = 0; + ptrA->bufferSizeE = 1024; + + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; + ptrA->maxRadiusE = 0; + ptrA->patchWidthE = 0; + ptrA->patchHeightE = 0; + ptrA->minScaleE = 0; + ptrA->maxScaleE = 0; + ptrA->scaleStepE = 0; + ptrA->borderWidthE = 0; + ptrA->borderHeightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_copy( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + const struct bbf_Scanner* srcPtrA ) +{ + ptrA->scaleExpE = srcPtrA->scaleExpE; + ptrA->scaleE = srcPtrA->scaleE; + ptrA->xE = srcPtrA->xE; + ptrA->yE = srcPtrA->yE; + ptrA->effMaxScaleE = srcPtrA->effMaxScaleE; + ptrA->currentWidthE = srcPtrA->currentWidthE; + ptrA->currentHeightE = srcPtrA->currentHeightE; + ptrA->workWidthE = srcPtrA->workWidthE; + ptrA->workHeightE = srcPtrA->workHeightE; + + bbf_BitParam_copy( cpA, &ptrA->bitParamE, &srcPtrA->bitParamE ); + bbs_UInt16Arr_copy( cpA, &ptrA->workImageE, &srcPtrA->workImageE ); + bim_UInt32Image_copy( cpA, &ptrA->satE, &srcPtrA->satE ); + bim_UInt32Image_copy( cpA, &ptrA->bitImageE, &srcPtrA->bitImageE ); + bbs_UInt32Arr_copy( cpA, &ptrA->patchBufferE, &srcPtrA->patchBufferE ); + bbs_UInt16Arr_copy( cpA, &ptrA->lineBufE, &srcPtrA->lineBufE ); + + ptrA->maxImageWidthE = srcPtrA->maxImageWidthE; + ptrA->maxImageHeightE = srcPtrA->maxImageHeightE; + ptrA->maxRadiusE = srcPtrA->maxRadiusE; + ptrA->patchWidthE = srcPtrA->patchWidthE; + ptrA->patchHeightE = srcPtrA->patchHeightE; + ptrA->minScaleE = srcPtrA->minScaleE; + ptrA->maxScaleE = srcPtrA->maxScaleE; + ptrA->scaleStepE = srcPtrA->scaleStepE; + ptrA->borderWidthE = srcPtrA->borderWidthE; + ptrA->borderHeightE = srcPtrA->borderHeightE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_Scanner_equal( struct bbs_Context* cpA, + const struct bbf_Scanner* ptrA, + const struct bbf_Scanner* srcPtrA ) +{ + if( ptrA->maxImageWidthE != srcPtrA->maxImageWidthE ) return FALSE; + if( ptrA->maxImageHeightE != srcPtrA->maxImageHeightE ) return FALSE; + if( ptrA->maxRadiusE != srcPtrA->maxRadiusE ) return FALSE; + if( ptrA->patchWidthE != srcPtrA->patchWidthE ) return FALSE; + if( ptrA->patchHeightE != srcPtrA->patchHeightE ) return FALSE; + if( ptrA->minScaleE != srcPtrA->minScaleE ) return FALSE; + if( ptrA->maxScaleE != srcPtrA->maxScaleE ) return FALSE; + if( ptrA->scaleStepE != srcPtrA->scaleStepE ) return FALSE; + if( ptrA->borderWidthE != srcPtrA->borderWidthE ) return FALSE; + if( ptrA->borderHeightE != srcPtrA->borderHeightE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Scanner_positions( const struct bbf_Scanner* ptrA ) +{ + int32 wL = ( int32 )ptrA->currentWidthE - ptrA->patchWidthE; + int32 hL = ( int32 )ptrA->currentHeightE - ptrA->patchHeightE; + return ( wL >= 0 ? wL : 0 ) * ( hL >= 0 ? hL : 0 ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Scanner_scanIndex( const struct bbf_Scanner* ptrA ) +{ + return ptrA->yE * ptrA->currentWidthE + ptrA->xE; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_pos( const struct bbf_Scanner* ptrA, + int32* xPtrA, int32* yPtrA, uint32* scalePtrA ) +{ + /* 16.16 */ + *xPtrA = ( int32 )( ptrA->xE - ptrA->borderWidthE ) * ( int32 )( ptrA->scaleE >> 4 ); + + /* 16.16 */ + *yPtrA = ( int32 )( ptrA->yE - ptrA->borderHeightE ) * ( int32 )( ptrA->scaleE >> 4 ); + + /* 12.20 */ + *scalePtrA = ptrA->scaleE; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_idxPos( const struct bbf_Scanner* ptrA, uint32 scanIndexA, + int32* xPtrA, int32* yPtrA, uint32* scalePtrA ) +{ + int32 yL = scanIndexA / ptrA->currentWidthE; + int32 xL = scanIndexA - ( yL * ptrA->currentWidthE ); + + /* 16.16 */ + *xPtrA = ( int32 )( xL - ptrA->borderWidthE ) * ( int32 )( ptrA->scaleE >> 4 ); + + /* 16.16 */ + *yPtrA = ( int32 )( yL - ptrA->borderHeightE ) * ( int32 )( ptrA->scaleE >> 4 ); + + *scalePtrA = ptrA->scaleE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_create( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + flag maximizeSharedMemoryA, + uint32 maxImageWidthA, + uint32 maxImageHeightA, + uint32 maxRadiusA, + uint32 patchWidthA, + uint32 patchHeightA, + uint32 minScaleA, + uint32 maxScaleA, + uint32 scaleStepA, + uint32 borderWidthA, + uint32 borderHeightA, + uint32 bufferSizeA, + struct bbs_MemTbl* mtpA ) +{ + ptrA->maxImageWidthE = maxImageWidthA; + ptrA->maxImageHeightE = maxImageHeightA; + ptrA->maxRadiusE = maxRadiusA; + ptrA->patchWidthE = patchWidthA; + ptrA->patchHeightE = patchHeightA; + ptrA->minScaleE = minScaleA; + ptrA->maxScaleE = maxScaleA; + ptrA->scaleStepE = scaleStepA; + ptrA->borderWidthE = borderWidthA; + ptrA->borderHeightE = borderHeightA; + ptrA->bufferSizeE = bufferSizeA; + bbf_Scanner_alloc( cpA, ptrA, mtpA, maximizeSharedMemoryA ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_bitParam( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + const struct bbf_BitParam* bitParamPtrA ) +{ + if( !bbf_BitParam_equal( cpA, &ptrA->bitParamE, bitParamPtrA ) ) + { + bbf_BitParam_copy( cpA, &ptrA->bitParamE, bitParamPtrA ); + bbf_Scanner_createBitImage( cpA, ptrA ); + } + + bbf_Scanner_resetScan( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Scanner_memSize( struct bbs_Context* cpA, + const struct bbf_Scanner* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + memSizeL += bbs_SIZEOF16( ptrA->maxImageWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->maxImageHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->maxRadiusE ); + memSizeL += bbs_SIZEOF16( ptrA->patchWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->patchHeightE ); + memSizeL += bbs_SIZEOF16( ptrA->minScaleE ); + memSizeL += bbs_SIZEOF16( ptrA->maxScaleE ); + memSizeL += bbs_SIZEOF16( ptrA->scaleStepE ); + memSizeL += bbs_SIZEOF16( ptrA->borderWidthE ); + memSizeL += bbs_SIZEOF16( ptrA->borderHeightE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Scanner_memWrite( struct bbs_Context* cpA, + const struct bbf_Scanner* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bbf_Scanner_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_SCANNER_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxImageWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxImageHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxRadiusE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->minScaleE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxScaleE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->scaleStepE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->borderWidthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->borderHeightE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Scanner_memRead( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_SCANNER_VERSION, memPtrA ); + + memPtrA += bbs_memRead32( &ptrA->maxImageWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxImageHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxRadiusE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->minScaleE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxScaleE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->scaleStepE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->borderWidthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->borderHeightE, memPtrA ); + + if( memSizeL != bbf_Scanner_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_Scanner_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + if( bbs_Context_error( cpA ) ) return 0; + + /* allocate arrays */ + bbf_Scanner_alloc( cpA, ptrA, mtpA, FALSE ); + + if( bbs_Context_error( cpA ) ) return 0; + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_resetScan( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + bbf_Scanner_initPatchBuffer( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_assign( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, + const void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA, + const struct bbf_BitParam* paramPtrA ) +{ + /* copy image */ + bbf_Scanner_copyImage( cpA, ptrA, imagePtrA, imageWidthA, imageHeightA, roiPtrA ); + + ptrA->scaleE = ptrA->minScaleE; + bbf_BitParam_copy( cpA, &ptrA->bitParamE, paramPtrA ); + + /* compute effective max scale */ + { + /* 16.16 */ + uint32 maxHScaleL = ( ptrA->workWidthE << 16 ) / ( ptrA->patchWidthE + 1 ); + uint32 maxVScaleL = ( ptrA->workHeightE << 16 ) / ( ptrA->patchHeightE + 1 ); + + /* 12.20 */ + ptrA->effMaxScaleE = maxHScaleL < maxVScaleL ? ( maxHScaleL << 4 ) : ( maxVScaleL << 4 ); + + if( ptrA->maxScaleE > 0 ) ptrA->effMaxScaleE = ptrA->effMaxScaleE < ptrA->maxScaleE ? ptrA->effMaxScaleE : ptrA->maxScaleE; + } + + ptrA->scaleExpE = 0; + + /* downscale work image if necessary */ + while( ptrA->scaleE > ( ( uint32 )( 2 << ptrA->scaleExpE ) << 20 ) ) bbf_Scanner_downscale( cpA, ptrA ); + + bbf_Scanner_createBitImage( cpA, ptrA ); + bbf_Scanner_resetScan( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_Scanner_nextScale( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + if( ptrA->scaleE + bbf_Scanner_scalePrd( ptrA->scaleE, ptrA->scaleStepE ) >= ptrA->effMaxScaleE ) return FALSE; + ptrA->scaleE += bbf_Scanner_scalePrd( ptrA->scaleE, ptrA->scaleStepE ); + + /* downscale work image if necessary */ + while( ptrA->scaleE > ( ( uint32 )( 2 << ptrA->scaleExpE ) << 20 ) ) bbf_Scanner_downscale( cpA, ptrA ); + + bbf_Scanner_createBitImage( cpA, ptrA ); + bbf_Scanner_resetScan( cpA, ptrA ); + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +const uint32* bbf_Scanner_getPatch( const struct bbf_Scanner* ptrA ) +{ + return ptrA->patchBufferE.arrPtrE + ptrA->xE; +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_Scanner_next( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + if( ( ptrA->xE + 1 ) < ( int32 )( ptrA->currentWidthE - ptrA->patchWidthE ) ) + { + ptrA->xE++; + return TRUE; + } + + if( ( ptrA->yE + 1 ) >= ( int32 )( ptrA->currentHeightE - ptrA->patchHeightE ) ) return FALSE; + + ptrA->xE = 0; + ptrA->yE++; + + { + uint32 offL = ( ptrA->yE & 0x1F ); + uint32 rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 ); + + uint32 sizeL = ptrA->bitImageE.widthE; + uint32* dstL = ptrA->patchBufferE.arrPtrE; + uint32 iL; + + if( rowL < ptrA->bitImageE.heightE ) + { + uint32* srcL = ( uint32* )ptrA->bitImageE.arrE.arrPtrE + rowL * sizeL; + if( offL > 0 ) + { + uint32 shlL = 32 - offL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( dstL[ iL ] >> 1 ) | ( srcL[ iL ] << shlL ); + } + else + { + bbs_memcpy32( dstL, srcL, sizeL ); + } + } + else + { + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] >>= 1; + } + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_goToXY( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, int32 xA, int32 yA ) +{ + bbs_DEF_fNameL( "void bbf_Scanner_goToXY( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, int32 xA, int32 yA )" ) + + if( xA > ( int32 )( ptrA->currentWidthE - ptrA->patchWidthE ) ) + { + bbs_ERROR1( "%s:\nyA out of range", fNameL ); + return; + } + + ptrA->xE = xA; + + if( ptrA->yE == yA ) return; + + if( yA >= ( int32 )( ptrA->currentHeightE - ptrA->patchHeightE ) ) + { + bbs_ERROR1( "%s:\nyA out of range", fNameL ); + return; + } + + if( yA == ptrA->yE + 1 ) + { + uint32 offL, rowL; + uint32 sizeL; + uint32* dstL; + uint32 iL; + + ptrA->yE = yA; + offL = ( ptrA->yE & 0x1F ); + rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 ); + + sizeL = ptrA->bitImageE.widthE; + dstL = ptrA->patchBufferE.arrPtrE; + + if( rowL < ptrA->bitImageE.heightE ) + { + uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + rowL * sizeL; + if( offL > 0 ) + { + uint32 shlL = 32 - offL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( dstL[ iL ] >> 1 ) | ( srcL[ iL ] << shlL ); + } + else + { + bbs_memcpy32( dstL, srcL, sizeL ); + } + } + else + { + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] >>= 1; + } + } + else + { + uint32 offL, rowL; + uint32 sizeL; + uint32* dstL; + uint32 iL; + + ptrA->yE = yA; + offL = ( ptrA->yE & 0x1F ); + rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 ); + + sizeL = ptrA->bitImageE.widthE; + dstL = ptrA->patchBufferE.arrPtrE; + + if( rowL < ptrA->bitImageE.heightE ) + { + if( offL > 0 ) + { + uint32* src1L = ptrA->bitImageE.arrE.arrPtrE + rowL * sizeL; + uint32* src0L = src1L - sizeL; + uint32 shlL = 32 - offL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( src0L[ iL ] >> offL ) | ( src1L[ iL ] << shlL ); + } + else + { + bbs_memcpy32( dstL, ptrA->bitImageE.arrE.arrPtrE + rowL * sizeL, sizeL ); + } + } + else + { + uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + ( rowL - 1 ) * sizeL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = srcL[ iL ] >> offL; + } + } +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_goToIndex( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, uint32 scanIndexA ) +{ + int32 yL = scanIndexA / ptrA->currentWidthE; + int32 xL = scanIndexA - yL * ptrA->currentWidthE; + bbf_Scanner_goToXY( cpA, ptrA, xL, yL ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Scanner_goToUls( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, + int32 xA, int32 yA, uint32 scaleA ) +{ + int32 xL = ( xA / ( int32 )( ptrA->scaleE >> 4 ) ) + ptrA->borderWidthE; + int32 yL = ( yA / ( int32 )( ptrA->scaleE >> 4 ) ) + ptrA->borderHeightE; + + if( ptrA->scaleE != scaleA ) + { + bbs_ERROR0( "bbf_Scanner_goToUls:\nScales no not match" ); + return; + } + + bbf_Scanner_goToXY( cpA, ptrA, xL, yL ); +} + +/* ------------------------------------------------------------------------- */ + +/* resets output positions */ +void bbf_Scanner_resetOutPos( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + ptrA->outCountE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* resets internal positions */ +void bbf_Scanner_resetIntPos( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) +{ + ptrA->intCountE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* add internal position */ +void bbf_Scanner_addIntPos( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + uint32 idxA, + int32 actA ) +{ + if( ptrA->intCountE < ptrA->idxArrE.sizeE ) + { + ptrA->idxArrE.arrPtrE[ ptrA->intCountE ] = idxA; + ptrA->actArrE.arrPtrE[ ptrA->intCountE ] = actA; + ptrA->intCountE++; + } + else + { + /* When buffer is full then replace lowest confidence-entry with new input + * This fallback solution causes soft degradation of performance when the buffer limit is reached. + */ + int32 minActL = 0x7FFFFFFF; + uint32 minIdxL = 0; + uint32 iL; + int32* actArrL = ptrA->actArrE.arrPtrE; + for( iL = 0; iL < ptrA->intCountE; iL++ ) + { + if( actArrL[ iL ] < minActL ) + { + minActL = actArrL[ iL ]; + minIdxL = iL; + } + } + + if( actA > minActL ) + { + ptrA->idxArrE.arrPtrE[ minIdxL ] = idxA; + ptrA->actArrE.arrPtrE[ minIdxL ] = actA; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* add external position */ +void bbf_Scanner_addOutPos( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + int32 xA, + int32 yA, + uint32 scaleA, + int32 actA ) +{ + if( ( ptrA->outCountE * 4 ) < ptrA->outArrE.sizeE ) + { + ptrA->outArrE.arrPtrE[ ptrA->outCountE * 4 + 0 ] = xA; + ptrA->outArrE.arrPtrE[ ptrA->outCountE * 4 + 1 ] = yA; + ptrA->outArrE.arrPtrE[ ptrA->outCountE * 4 + 2 ] = scaleA; + ptrA->outArrE.arrPtrE[ ptrA->outCountE * 4 + 3 ] = actA; + ptrA->outCountE++; + } + else + { + /* When buffer is full then replace lowest confidence-entry with new input + * This fallback solution causes soft degradation of performance when the buffer limit is reached. + */ + int32 minActL = 0x7FFFFFFF; + uint32 minIdxL = 0; + uint32 iL; + int32* outArrL = ptrA->outArrE.arrPtrE; + for( iL = 0; iL < ptrA->outCountE; iL++ ) + { + if( outArrL[ iL * 4 + 3 ] < minActL ) + { + minActL = outArrL[ iL * 4 + 3 ]; + minIdxL = iL; + } + } + + if( actA > minActL ) + { + ptrA->idxArrE.arrPtrE[ minIdxL * 4 + 0 ] = xA; + ptrA->idxArrE.arrPtrE[ minIdxL * 4 + 1 ] = yA; + ptrA->idxArrE.arrPtrE[ minIdxL * 4 + 2 ] = scaleA; + ptrA->idxArrE.arrPtrE[ minIdxL * 4 + 3 ] = actA; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* remove overlaps */ +uint32 bbf_Scanner_removeOutOverlaps( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + uint32 overlapThrA ) +{ + uint32 begIdxL = 0; /* begin index */ + uint32 endIdxL = ptrA->outCountE; /* end index */ + uint32 iL; + uint32 rw0L = ptrA->patchWidthE; + uint32 rh0L = ptrA->patchHeightE; + int32* outArrL = ptrA->outArrE.arrPtrE; + + if( overlapThrA >= 0x010000 ) return ptrA->outCountE; + + while( endIdxL - begIdxL > 1 ) + { + int32 x1L, y1L, s1L, a1L; + int32 r1wL, r1hL; + uint32 r1aL; + + /* find maximum activity */ + uint32 maxIdxL = 0; + + { + int32 maxActL = ( int32 )0x80000000; + for( iL = begIdxL; iL < endIdxL; iL++ ) + { + if( outArrL[ iL * 4 + 3 ] > maxActL ) + { + maxActL = outArrL[ iL * 4 + 3 ]; + maxIdxL = iL; + } + } + } + + /* swap with position 0 */ + x1L = outArrL[ maxIdxL * 4 + 0 ]; + y1L = outArrL[ maxIdxL * 4 + 1 ]; + s1L = outArrL[ maxIdxL * 4 + 2 ]; + a1L = outArrL[ maxIdxL * 4 + 3 ]; + + outArrL[ maxIdxL * 4 + 0 ] = outArrL[ begIdxL * 4 + 0 ]; + outArrL[ maxIdxL * 4 + 1 ] = outArrL[ begIdxL * 4 + 1 ]; + outArrL[ maxIdxL * 4 + 2 ] = outArrL[ begIdxL * 4 + 2 ]; + outArrL[ maxIdxL * 4 + 3 ] = outArrL[ begIdxL * 4 + 3 ]; + + outArrL[ begIdxL * 4 + 0 ] = x1L; + outArrL[ begIdxL * 4 + 1 ] = y1L; + outArrL[ begIdxL * 4 + 2 ] = s1L; + outArrL[ begIdxL * 4 + 3 ] = a1L; + + /* rectangle */ + r1wL = ( rw0L * ( s1L >> 12 ) + 128 ) >> 8; + r1hL = ( rh0L * ( s1L >> 12 ) + 128 ) >> 8; + r1aL = ( uint32 )r1wL * ( uint32 )r1hL; + + /* remove coordinate fractions */ + x1L = ( x1L + ( 1 << 15 ) ) >> 16; + y1L = ( y1L + ( 1 << 15 ) ) >> 16; + + /* compare to other rectangles and remove overlaps */ + for( iL = endIdxL - 1; iL > begIdxL; iL-- ) + { + int32* x2pL = &outArrL[ iL * 4 + 0 ]; + int32* y2pL = &outArrL[ iL * 4 + 1 ]; + int32* s2pL = &outArrL[ iL * 4 + 2 ]; + int32* a2pL = &outArrL[ iL * 4 + 3 ]; + + int32 x2L = ( *x2pL + ( 1 << 15 ) ) >> 16; + int32 y2L = ( *y2pL + ( 1 << 15 ) ) >> 16; + + /* rectangle */ + int32 r2wL = ( rw0L * ( *s2pL >> 12 ) + 128 ) >> 8; + int32 r2hL = ( rh0L * ( *s2pL >> 12 ) + 128 ) >> 8; + uint32 r2aL = r2wL * r2hL; + + /* intersection */ + int32 rx1L = x1L > x2L ? x1L : x2L; + int32 rx2L = ( x1L + r1wL ) < ( x2L + r2wL ) ? ( x1L + r1wL ) : ( x2L + r2wL ); + int32 ry1L = y1L > y2L ? y1L : y2L; + int32 ry2L = ( y1L + r1hL ) < ( y2L + r2hL ) ? ( y1L + r1hL ) : ( y2L + r2hL ); + uint32 riwL; + + rx2L = ( rx2L > rx1L ) ? rx2L : rx1L; + ry2L = ( ry2L > ry1L ) ? ry2L : ry1L; + riwL = ( uint32 )( rx2L - rx1L ) * ( uint32 )( ry2L - ry1L ); + + if( riwL > ( ( ( overlapThrA >> 8 ) * ( r1aL < r2aL ? r1aL : r2aL ) ) >> 8 ) ) + { + endIdxL--; + *x2pL = outArrL[ endIdxL * 4 + 0 ]; + *y2pL = outArrL[ endIdxL * 4 + 1 ]; + *s2pL = outArrL[ endIdxL * 4 + 2 ]; + *a2pL = outArrL[ endIdxL * 4 + 3 ]; + } + } + + begIdxL++; + } + + ptrA->outCountE = endIdxL; + + return endIdxL; +} + +/* ------------------------------------------------------------------------- */ + +/* remove internal overlaps */ +uint32 bbf_Scanner_removeIntOverlaps( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + uint32 overlapThrA ) +{ + uint32 begIdxL = 0; /* begin index */ + uint32 endIdxL = ptrA->intCountE; /* end index */ + uint32 iL; + uint32 rw0L = ptrA->patchWidthE; + uint32 rh0L = ptrA->patchHeightE; + int32 minAreaL = ( overlapThrA * rw0L * rh0L ) >> 16; + + int32* actArrL = ptrA->actArrE.arrPtrE; + uint32* idxArrL = ptrA->idxArrE.arrPtrE; + + if( overlapThrA >= 0x010000 ) return ptrA->intCountE; + + while( endIdxL - begIdxL > 1 ) + { + /* find maximum activity */ + int32 a1L = ( int32 )0x80000000; + uint32 i1L = 0; + uint32 maxIdxL = 0; + int32 x1L, y1L; + + for( iL = begIdxL; iL < endIdxL; iL++ ) + { + if( actArrL[ iL ] > a1L ) + { + a1L = actArrL[ iL ]; + maxIdxL = iL; + } + } + + /* swap with position 0 */ + i1L = idxArrL[ maxIdxL ]; + idxArrL[ maxIdxL ] = idxArrL[ begIdxL ]; + actArrL[ maxIdxL ] = actArrL[ begIdxL ]; + idxArrL[ begIdxL ] = i1L; + actArrL[ begIdxL ] = a1L; + + /* upper left coordinates */ + y1L = i1L / ptrA->currentWidthE; + x1L = i1L - ( y1L * ptrA->currentWidthE ); + + /* compare to other rectangles and remove overlaps */ + for( iL = endIdxL - 1; iL > begIdxL; iL-- ) + { + int32* a2pL = &actArrL[ iL ]; + uint32* i2pL = &idxArrL[ iL ]; + + int32 y2L = *i2pL / ptrA->currentWidthE; + int32 x2L = *i2pL - ( y2L * ptrA->currentWidthE ); + + int32 dxL = rw0L - ( x1L > x2L ? x1L - x2L : x2L - x1L ); + int32 dyL = rh0L - ( y1L > y2L ? y1L - y2L : y2L - y1L ); + + dxL = dxL > 0 ? dxL : 0; + dyL = dyL > 0 ? dyL : 0; + + if( dxL * dyL > minAreaL ) + { + endIdxL--; + *a2pL = actArrL[ endIdxL ]; + *i2pL = idxArrL[ endIdxL ]; + } + } + + begIdxL++; + } + + ptrA->intCountE = endIdxL; + + return ptrA->intCountE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_BitFeatureEm/Scanner.h b/Embedded/common/src/b_BitFeatureEm/Scanner.h new file mode 100644 index 0000000..31787e8 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Scanner.h @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_SCANNER_EM_H +#define bbf_SCANNER_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/UInt32Arr.h" +#include "b_BasicEm/Int32Arr.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BasicEm/UInt16Arr.h" +#include "b_ImageEm/UInt32Image.h" + +#include "b_BitFeatureEm/Feature.h" +#include "b_BitFeatureEm/BitParam.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bbf_SCANNER_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** scans an image and provides patches as needed */ +struct bbf_Scanner +{ + /* ---- private data --------------------------------------------------- */ + + /** downscale exponent */ + uint32 scaleExpE; + + /** current scale (12.20) */ + uint32 scaleE; + + /** current scan x-coordinate */ + int32 xE; + + /** current scan y-coordinate */ + int32 yE; + + /** effective maximum scale (12.20) */ + uint32 effMaxScaleE; + + /** width of scaled image */ + uint32 currentWidthE; + + /** height of scaled image */ + uint32 currentHeightE; + + /** width of work image */ + uint32 workWidthE; + + /** height of work image */ + uint32 workHeightE; + + /** parameter for bit generation */ + struct bbf_BitParam bitParamE; + + /** work image (two pixels per uint16)*/ + struct bbs_UInt16Arr workImageE; + + /** summed-area table (ring buffer) */ + struct bim_UInt32Image satE; + + /** bit image */ + struct bim_UInt32Image bitImageE; + + /** patch buffer */ + struct bbs_UInt32Arr patchBufferE; + + /** image line buffer */ + struct bbs_UInt16Arr lineBufE; + + + + /** index position buffer */ + struct bbs_UInt32Arr idxArrE; + + /** activity buffer */ + struct bbs_Int32Arr actArrE; + + /** composite output buffer */ + struct bbs_Int32Arr outArrE; + + /* internal positions detected */ + uint32 intCountE; + + /* output positions detected */ + uint32 outCountE; + + /** Face positions buffer size (approx.: max faces * 20...60) + * This variable is not part of I/O and must be set before calling memRead + * Default value: 1024 -> about 100...200 faces/image detectable + * + * The Scanner allocates internally bufferSizeE * 10 bytes of exclusive memory + */ + uint32 bufferSizeE; + + /* ---- public data ---------------------------------------------------- */ + + /** maximum image width */ + uint32 maxImageWidthE; + + /** maximum image height */ + uint32 maxImageHeightE; + + /** maximum filter radius */ + uint32 maxRadiusE; + + /** patch width */ + uint32 patchWidthE; + + /** patch height */ + uint32 patchHeightE; + + /** minimum scale (12.20) */ + uint32 minScaleE; + + /** maximum scale (12.20) (0: unlimited) */ + uint32 maxScaleE; + + /** scale step factor (1.32) (leading bit is always one and therfore ignored) */ + uint32 scaleStepE; + + /** x-border in pixels */ + uint32 borderWidthE; + + /** y-border in pixels */ + uint32 borderHeightE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_Scanner */ +void bbf_Scanner_init( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA ); + +/** resets bbf_Scanner */ +void bbf_Scanner_exit( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_Scanner_copy( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + const struct bbf_Scanner* srcPtrA ); + +/** equal operator */ +flag bbf_Scanner_equal( struct bbs_Context* cpA, + const struct bbf_Scanner* ptrA, + const struct bbf_Scanner* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** scan positions at current scale */ +uint32 bbf_Scanner_positions( const struct bbf_Scanner* ptrA ); + +/** current scan index */ +uint32 bbf_Scanner_scanIndex( const struct bbf_Scanner* ptrA ); + +/** returns current uls position relative to original image; x,y: 16.16; scale: 12.20 */ +void bbf_Scanner_pos( const struct bbf_Scanner* ptrA, + int32* xPtrA, int32* yPtrA, uint32* scalePtrA ); + +/** returns uls position relative to original image at index position; x,y: 16.16; scale: 12.20 */ +void bbf_Scanner_idxPos( const struct bbf_Scanner* ptrA, uint32 scanIndexA, + int32* xPtrA, int32* yPtrA, uint32* scalePtrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** creates & initializes object */ +void bbf_Scanner_create( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + flag maximizeSharedMemoryA, + uint32 maxImageWidthA, + uint32 maxImageHeightA, + uint32 maxRadiusA, + uint32 patchWidthA, + uint32 patchHeightA, + uint32 minScaleA, + uint32 maxScaleA, + uint32 scaleStepA, + uint32 borderWidthA, + uint32 borderHeightA, + uint32 bufferSizeA, + struct bbs_MemTbl* mtpA ); + +/** parameter for bit generation + recomputing bit image */ +void bbf_Scanner_bitParam( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + const struct bbf_BitParam* bitParamPtrA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_Scanner_memSize( struct bbs_Context* cpA, + const struct bbf_Scanner* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_Scanner_memWrite( struct bbs_Context* cpA, + const struct bbf_Scanner* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_Scanner_memRead( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** resets scan position at current scale level */ +void bbf_Scanner_resetScan( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ); + +/** Assigns image; sets initial bit parameters; resets processor. + * If roiPtrA is NULL, the whole image is considered for processsing + * otherwise *roiPtrA specifies a section of the original image to which + * procesing is limited. All coordinates refer to that section and must + * eventually be corrected externally. + * The roi rectangle must not include pixels outside of the original image + * (checked -> error). The rectangle may be of uneven width. + */ +void bbf_Scanner_assign( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, + const void* imagePtrA, + uint32 imageWidthA, + uint32 imageHeightA, + const struct bts_Int16Rect* roiPtrA, + const struct bbf_BitParam* paramPtrA ); + +/** goes to next scale position */ +flag bbf_Scanner_nextScale( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ); + +/** returns pointer to patch data */ +const uint32* bbf_Scanner_getPatch( const struct bbf_Scanner* ptrA ); + +/** goes to next scan position */ +flag bbf_Scanner_next( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ); + +/** goes to scan position */ +void bbf_Scanner_goToXY( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, int32 xA, int32 yA ); + +/** goes to scan index position */ +void bbf_Scanner_goToIndex( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, uint32 scanIndexA ); + +/** goes to scan position from image uls position (error if scales do not match); x,y: 16.16; scale: 12.20 */ +void bbf_Scanner_goToUls( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, + int32 xA, int32 yA, uint32 scaleA ); + +/** The functions below offer positions management of temporary positions needed by the detector object */ + +/** resets internal positions */ +void bbf_Scanner_resetIntPos( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ); + +/** reset output positions */ +void bbf_Scanner_resetOutPos( struct bbs_Context* cpA, struct bbf_Scanner* ptrA ) ; + +/* add internal position */ +void bbf_Scanner_addIntPos( struct bbs_Context* cpA, struct bbf_Scanner* ptrA, uint32 idxA, int32 actA ); + +/* add external position */ +void bbf_Scanner_addOutPos( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + int32 xA, + int32 yA, + uint32 scaleA, + int32 actA ); + +/* removes internal overlaps */ +uint32 bbf_Scanner_removeIntOverlaps( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + uint32 overlapThrA ); + +/** removes output overlaps */ +uint32 bbf_Scanner_removeOutOverlaps( struct bbs_Context* cpA, + struct bbf_Scanner* ptrA, + uint32 overlapThrA ); + +#endif /* bbf_SCANNER_EM_H */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Sequence.c b/Embedded/common/src/b_BitFeatureEm/Sequence.c new file mode 100644 index 0000000..e25373f --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Sequence.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BitFeatureEm/Sequence.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Sequence_init( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA ) +{ + bbs_memset16( ptrA->ftrPtrArrE, 0, bbs_SIZEOF16( ptrA->ftrPtrArrE ) ); + + bbf_Feature_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bbf_FT_SEQUENCE; + ptrA->baseE.vpActivityE = bbf_Sequence_activity; + ptrA->sizeE = 0; + bbs_Int32Arr_init( cpA, &ptrA->thrArrE ); + bbs_UInt16Arr_init( cpA, &ptrA->wgtArrE ); + bbs_UInt16Arr_init( cpA, &ptrA->dataArrE ); +} + +/* ------------------------------------------------------------------------- */ + +void bbf_Sequence_exit( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA ) +{ + uint16 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) bbf_featureExit( cpA, ptrA->ftrPtrArrE[ iL ] ); + + bbs_memset16( ptrA->ftrPtrArrE, 0, bbs_SIZEOF16( ptrA->ftrPtrArrE ) ); + bbf_Feature_exit( cpA, &ptrA->baseE ); + ptrA->sizeE = 0; + bbs_Int32Arr_exit( cpA, &ptrA->thrArrE ); + bbs_UInt16Arr_exit( cpA, &ptrA->wgtArrE ); + bbs_UInt16Arr_exit( cpA, &ptrA->dataArrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bbf_Sequence_copy( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA, + const struct bbf_Sequence* srcPtrA ) +{ + bbs_ERROR0( "bbf_Sequence_copy:\n Function is not available" ); +} + +/* ------------------------------------------------------------------------- */ + +flag bbf_Sequence_equal( struct bbs_Context* cpA, + const struct bbf_Sequence* ptrA, + const struct bbf_Sequence* srcPtrA ) +{ + bbs_ERROR0( "bbf_Sequence_equal:\n Function is not available" ); + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Sequence_memSize( struct bbs_Context* cpA, + const struct bbf_Sequence* ptrA ) +{ + uint16 iL; + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bbf_Feature_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_SIZEOF16( ptrA->sizeE ); + memSizeL += bbs_Int32Arr_memSize( cpA, &ptrA->thrArrE ); + memSizeL += bbs_UInt16Arr_memSize( cpA, &ptrA->wgtArrE ); + for( iL = 0; iL < ptrA->sizeE; iL++ ) memSizeL += bbf_featureMemSize( cpA, ptrA->ftrPtrArrE[ iL ] ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Sequence_memWrite( struct bbs_Context* cpA, + const struct bbf_Sequence* ptrA, + uint16* memPtrA ) +{ + uint16 iL; + uint32 memSizeL = bbf_Sequence_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bbf_SEQUENCE_VERSION, memPtrA ); + memPtrA += bbf_Feature_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_Int32Arr_memWrite( cpA, &ptrA->thrArrE, memPtrA ); + memPtrA += bbs_UInt16Arr_memWrite( cpA, &ptrA->wgtArrE, memPtrA ); + for( iL = 0; iL < ptrA->sizeE; iL++ ) memPtrA += bbf_featureMemWrite( cpA, ptrA->ftrPtrArrE[ iL ], memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bbf_Sequence_memRead( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint16 iL; + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_fastestSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_SEQUENCE_VERSION, memPtrA ); + memPtrA += bbf_Feature_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->sizeE, memPtrA ); + + if( ptrA->sizeE > bbf_SEQUENCE_MAX_SIZE ) + { + bbs_ERROR0( "bbf_Sequence_memRead:\n Sequence size exceeds bbf_SEQUENCE_MAX_SIZE" ); + return 0; + } + + memPtrA += bbs_Int32Arr_memRead( cpA, &ptrA->thrArrE, memPtrA, espL ); + + if( versionL >= 101 ) memPtrA += bbs_UInt16Arr_memRead( cpA, &ptrA->wgtArrE, memPtrA, espL ); + + /* check features & allocate data buffer */ + { + const uint16* memPtrL = memPtrA; + uint32 dataSizeL = 0; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + enum bbf_FeatureType typeL = ( enum bbf_FeatureType )bbs_memPeek32( memPtrL + 4 ); + dataSizeL += bbf_featureSizeOf16( cpA, typeL ); + memPtrL += bbs_memPeek32( memPtrL ); + } + bbs_UInt16Arr_create( cpA, &ptrA->dataArrE, dataSizeL, espL ); + } + + /* load features & initialize pointers */ + { + uint16* dataPtrL = ptrA->dataArrE.arrPtrE; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + enum bbf_FeatureType typeL = ( enum bbf_FeatureType )bbs_memPeek32( memPtrA + 4 ); + ptrA->ftrPtrArrE[ iL ] = ( struct bbf_Feature* )dataPtrL; + bbf_featureInit( cpA, ptrA->ftrPtrArrE[ iL ], typeL ); + memPtrA += bbf_featureMemRead( cpA, ptrA->ftrPtrArrE[ iL ], memPtrA, &memTblL ); + dataPtrL += bbf_featureSizeOf16( cpA, typeL ); + } + } + +/* if( memSizeL != bbf_Sequence_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_Sequence_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } +*/ + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bbf_Sequence_activity( const struct bbf_Feature* ptrA, const uint32* patchA ) +{ + const struct bbf_Sequence* ptrL = ( struct bbf_Sequence* )ptrA; + + count_t iL; + + int32 sizeL = ptrL->sizeE; + + /* 12.20 */ + int32 actSumL = ( -sizeL ) << 20; + + if( sizeL == 0 ) return 0x10000000; /* 1.0 in 4.28 format */ + + if( ptrL->wgtArrE.sizeE == 0 ) + { + for( iL = 0; iL < ptrL->sizeE; iL++ ) + { + /* 4.28 */ + int32 actL = ptrL->ftrPtrArrE[ iL ]->vpActivityE( ptrL->ftrPtrArrE[ iL ], patchA ) - ptrL->thrArrE.arrPtrE[ iL ]; + actSumL += ( actL >> 8 ); + if( actL < 0 ) return ( actSumL / sizeL ) << 7; /* return 4.28 */ + } + } + else + { + for( iL = 0; iL < ptrL->sizeE; iL++ ) + { + /* 4.28 */ + int32 actL = ptrL->ftrPtrArrE[ iL ]->vpActivityE( ptrL->ftrPtrArrE[ iL ], patchA ) - ptrL->thrArrE.arrPtrE[ iL ]; + int32 wgtL = ptrL->wgtArrE.arrPtrE[ iL ]; + actL = ( actL >> 16 ) * wgtL + ( ( ( int32 )( actL & 0x0000FFFF ) * wgtL ) >> 16 ); + actSumL += ( actL >> 8 ); + if( actL < 0 ) return ( actSumL / sizeL ) << 7; /* return 4.28 */ + } + } + + actSumL += sizeL << 20; + + /* positive activity: ] 0, 1 ] */ + return ( actSumL / sizeL ) << 7; /* return 4.28 */ +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_BitFeatureEm/Sequence.h b/Embedded/common/src/b_BitFeatureEm/Sequence.h new file mode 100644 index 0000000..c03bb75 --- /dev/null +++ b/Embedded/common/src/b_BitFeatureEm/Sequence.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bbf_SEQUENCE_EM_H +#define bbf_SEQUENCE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Int32Arr.h" +#include "b_BasicEm/UInt16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_BitFeatureEm/Feature.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** data format version number */ +#define bbf_SEQUENCE_VERSION 101 + +/** maximum sequence size */ +#define bbf_SEQUENCE_MAX_SIZE 16 + +/* ---- object definition -------------------------------------------------- */ + +/** inhomogenious sequence of features */ +struct bbf_Sequence +{ + /* ---- public data ---------------------------------------------------- */ + + /** base element (must be first element) */ + struct bbf_Feature baseE; + + /* ---- private data --------------------------------------------------- */ + + /** feature pointer arrray */ + struct bbf_Feature* ftrPtrArrE[ bbf_SEQUENCE_MAX_SIZE ]; + + /* ---- public data ---------------------------------------------------- */ + + /** sequence size */ + uint32 sizeE; + + /** array of thresholds (4.28) */ + struct bbs_Int32Arr thrArrE; + + /** array of weights (0.16); value 1.0 is saturated to 0xFFFF */ + struct bbs_UInt16Arr wgtArrE; + + /** data array (contains feature elements) */ + struct bbs_UInt16Arr dataArrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bbf_Sequence */ +void bbf_Sequence_init( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA ); + +/** resets bbf_Sequence */ +void bbf_Sequence_exit( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bbf_Sequence_copy( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA, + const struct bbf_Sequence* srcPtrA ); + +/** equal operator */ +flag bbf_Sequence_equal( struct bbs_Context* cpA, + const struct bbf_Sequence* ptrA, + const struct bbf_Sequence* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bbf_Sequence_memSize( struct bbs_Context* cpA, + const struct bbf_Sequence* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bbf_Sequence_memWrite( struct bbs_Context* cpA, + const struct bbf_Sequence* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bbf_Sequence_memRead( struct bbs_Context* cpA, + struct bbf_Sequence* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes feature's activity (4.28) on the given patch */ +int32 bbf_Sequence_activity( const struct bbf_Feature* ptrA, const uint32* patchA ); + +#endif /* bbf_SEQUENCE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/APhImage.c b/Embedded/common/src/b_ImageEm/APhImage.c new file mode 100644 index 0000000..2c5c9a8 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/APhImage.c @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/APhImage.h" +#include "b_ImageEm/ComplexImage.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_init( struct bbs_Context* cpA, + struct bim_APhImage* ptrA ) +{ + bbs_APhArr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_create( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_APhImage_size( cpA, ptrA, widthA, heightA ); + } + else + { + bbs_APhArr_create( cpA, &ptrA->arrE, widthA * heightA, mspA ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_exit( struct bbs_Context* cpA, + struct bim_APhImage* ptrA ) +{ + bbs_APhArr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_copy( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + const struct bim_APhImage* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_APhImage_copy( struct bim_APhImage*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + bbs_APhArr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_APhImage_equal( struct bbs_Context* cpA, + const struct bim_APhImage* ptrA, + const struct bim_APhImage* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + return bbs_APhArr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_size( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + uint32 widthA, + uint32 heightA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < widthA * heightA ) + { + bbs_ERROR0( "void bim_APhImage_size( struct bim_APhImage*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } +#endif + ptrA->widthE = widthA; + ptrA->heightE = heightA; + bbs_APhArr_size( cpA, &ptrA->arrE, widthA * heightA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_APhImage_memSize( struct bbs_Context* cpA, + const struct bim_APhImage* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_APhArr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_APhImage_memWrite( struct bbs_Context* cpA, + const struct bim_APhImage* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_APhImage_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_APH_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + bbs_APhArr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_APhImage_memRead( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, widthL, heightL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_APH_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &widthL, memPtrA ); + memPtrA += bbs_memRead32( &heightL, memPtrA ); + + ptrA->widthE = widthL; + ptrA->heightE = heightL; + bbs_APhArr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_APhImage_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_APhImage_memRead( const struct bim_APhImage*, const void* ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_setAllPixels( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + struct bbs_APh valueA ) +{ + long iL; + struct bbs_APh* ptrL = ptrA->arrE.arrPtrE; + for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- ) + { + *ptrL++ = valueA; + } +} + +/* ------------------------------------------------------------------------- */ + +/** + | | | | + | (loop x1) | (loop x2) | (loop x3) | + o------------->-o------------>--o------------->-o + | | | | + | | | | + | | | | + | | | | + ( sectionL->x1E, sectionL->y1E ) | | +---------o- R-------------------------------|---------------- + | | | | | + | | | | | + | | | | | + | | | | | + (loop y1)| | | | + | | | | | + V | | | | + | | |( 0, 0 ) | | X +---------o------------------I-------------------------------------------------> + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + (loop y2)| | | | + | | | | | + | | | | | + | | | | | + V | | | | + | | | | | +---------o------------------|---------------I | + | | | ( srcPtrA->widthE, srcPtrA->heightE ) + | | | | + | | | | + | | | | + | | | | + | | | | + (loop y3)| | | + | | | | + | | | | + V | | | + | | | | +---------o--------------------------------------------------R + | ( sectionL->x2E, sectionL->y2E ) + | + Y | + | + | + V + + To understand how the algorithm work refer to the diagram above. + The image boundaries are indicated by letter "I" ( 0, 0 ) to ( srcPtrA->widthE, srcPtrA->heightE ) + The rectangle boundaries are indicated by letter "R" ( sectionPtrA->x1E, sectionPtrA->y1E ) to ( sectionPtrA->x2E, sectionPtrA->y2E ) + + In the above example the intersection of the image and the rectange is + ( 0, 0 ), ( srcPtrA->widthE, srcPtrA->heightE ) + + The size of the destination image is always ( ( sectionL->x2E, sectionL->y2E ) - ( sectionL->x1E, sectionL->y1E ) ) + + All coordinates are assumed to be relative to the original image. + + 1. parse all pixels in "loop y1" + 1.a. parse all pixels in "loop x1" + 1.b. parse all pixels in "loop x2" + 1.c. parse all pixels in "loop x3" + 2. parse all pixels in "loop y2" + 2.a. parse all pixels in "loop x1" + 2.b. parse all pixels in "loop x2" + 2.c. parse all pixels in "loop x3" + 3. parse all pixels in "loop y3" + 3.a. parse all pixels in "loop x1" + 3.b. parse all pixels in "loop x2" + 3.c. parse all pixels in "loop x3" + +*/ + +/** copies a section of given image */ +void bim_APhImage_copySection( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + const struct bim_APhImage* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ) +{ + + struct bbs_APh* srcPixelPtrL; + struct bbs_APh* dstPixelPtrL; + int32 yIndexL; + int32 xIndexL; + + struct bts_Int16Rect srcImageSubSectionL; + struct bts_Int16Rect sectionL; + + /* make sure that the rectangle passed is correct, in case the x2 < x1 or y2 < y1, swap them */ + sectionL.x1E = bbs_min( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.x2E = bbs_max( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.y1E = bbs_min( sectionPtrA->y1E, sectionPtrA->y2E ); + sectionL.y2E = bbs_max( sectionPtrA->y1E, sectionPtrA->y2E ); + + /* find the intersection betweem the rectangle and the image, the image always starts at 0,0 */ + srcImageSubSectionL.x1E = bbs_max( 0, sectionL.x1E ); + srcImageSubSectionL.y1E = bbs_max( 0, sectionL.y1E ); + srcImageSubSectionL.x2E = bbs_min( ( int32 ) srcPtrA->widthE, sectionL.x2E ); + srcImageSubSectionL.y2E = bbs_min( ( int32 ) srcPtrA->heightE, sectionL.y2E ); + + /* If the image and the rectangle do not intersect in X direction, set the intersecting rectangle to the image coordinates */ + if( srcImageSubSectionL.x2E < srcImageSubSectionL.x1E ) + { + srcImageSubSectionL.x1E = 0; + srcImageSubSectionL.x2E = srcPtrA->widthE; + } + /* do the same as above in the Y direction */ + if( srcImageSubSectionL.y2E < srcImageSubSectionL.y1E ) + { + srcImageSubSectionL.y1E = 0; + srcImageSubSectionL.y2E = srcPtrA->heightE; + } + + /* set size, and allocate required memory for the destination image if required */ + bim_APhImage_size( cpA, ptrA, sectionL.x2E - sectionL.x1E, sectionL.y2E - sectionL.y1E ); + + /* get the pointer to the destination image */ + dstPixelPtrL = ptrA->arrE.arrPtrE; + + /* 1. parse all pixels in "loop y1" */ + for( yIndexL = sectionL.y1E; yIndexL < srcImageSubSectionL.y1E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE; + + /* 1.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 1.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 1.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 2. parse all pixels in "loop y2" */ + for( ; yIndexL < srcImageSubSectionL.y2E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE + yIndexL * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 2.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 2.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 2.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 3. parse all pixels in "loop y3" */ + for( ; yIndexL < sectionL.y2E; yIndexL++ ) + { + srcPixelPtrL = srcPtrA->arrE.arrPtrE + ( srcImageSubSectionL.y2E - 1 ) * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 3.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 3.b. parse all pixels in "loop x3" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 3.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + +} + +/* ------------------------------------------------------------------------- */ + +void bim_APhImage_importComplex( struct bbs_Context* cpA, + struct bim_APhImage* dstPtrA, + const struct bim_ComplexImage* srcPtrA ) +{ + long iL; + struct bbs_APh* dstL; + const struct bbs_Complex* srcL; + bim_APhImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE ); + dstL = dstPtrA->arrE.arrPtrE; + srcL = srcPtrA->arrE.arrPtrE; + for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- ) + { + bbs_APh_importComplex( dstL++, srcL++ ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/APhImage.h b/Embedded/common/src/b_ImageEm/APhImage.h new file mode 100644 index 0000000..f4804da --- /dev/null +++ b/Embedded/common/src/b_ImageEm/APhImage.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_APH_IMAGE_EM_H +#define bim_APH_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/APhArr.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt2D.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bim_ComplexImage; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_APH_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** image of complex values (abs-phase format) */ +struct bim_APhImage +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** array of bytes */ + struct bbs_APhArr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_APhImage */ +void bim_APhImage_init( struct bbs_Context* cpA, + struct bim_APhImage* ptrA ); + +/** creates bim_APhImage object */ +void bim_APhImage_create( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ); + +/** frees bim_APhImage */ +void bim_APhImage_exit( struct bbs_Context* cpA, + struct bim_APhImage* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_APhImage_copy( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + const struct bim_APhImage* srcPtrA ); + +/** equal operator */ +flag bim_APhImage_equal( struct bbs_Context* cpA, + const struct bim_APhImage* ptrA, + const struct bim_APhImage* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** sets image size */ +void bim_APhImage_size( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + uint32 widthA, + uint32 heightA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) needs when written to memory */ +uint32 bim_APhImage_memSize( struct bbs_Context* cpA, + const struct bim_APhImage* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bim_APhImage_memWrite( struct bbs_Context* cpA, + const struct bim_APhImage* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bim_APhImage_memRead( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets all pixels to one value */ +void bim_APhImage_setAllPixels( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + struct bbs_APh valueA ); + +/** copies a section of given image */ +void bim_APhImage_copySection( struct bbs_Context* cpA, + struct bim_APhImage* ptrA, + const struct bim_APhImage* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ); + +/** import complex image */ +void bim_APhImage_importComplex( struct bbs_Context* cpA, + struct bim_APhImage* dstPtrA, + const struct bim_ComplexImage* srcPtrA ); + +#endif /* bim_APH_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/ComplexImage.c b/Embedded/common/src/b_ImageEm/ComplexImage.c new file mode 100644 index 0000000..cbcf0f3 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/ComplexImage.c @@ -0,0 +1,480 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/ComplexImage.h" +#include "b_ImageEm/APhImage.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_init( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA ) +{ + bbs_ComplexArr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_exit( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA ) +{ + bbs_ComplexArr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_copy( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + const struct bim_ComplexImage* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_ComplexImage_copy(...):\n" + "Unsufficient allocated memory in destination image." ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + bbs_ComplexArr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_ComplexImage_equal( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA, + const struct bim_ComplexImage* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + return bbs_ComplexArr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_ComplexImage_checkSum( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA ) +{ + uint32 sumL =0 ; + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + const struct bbs_Complex* ptrL = ptrA->arrE.arrPtrE; + for( iL =0; iL < sizeL; iL++ ) + { + sumL += ptrL->imagE + ptrL->realE; + ptrL++; + } + return sumL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_ComplexImage_heapSize( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA, + uint32 widthA, uint32 heightA ) +{ + return bbs_ComplexArr_heapSize( cpA, &ptrA->arrE, widthA * heightA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_create( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_ComplexImage_size( cpA, ptrA, widthA, heightA ); + } + else + { + bbs_ComplexArr_create( cpA, &ptrA->arrE, widthA * heightA, mspA ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_size( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + uint32 widthA, + uint32 heightA ) +{ + if( ptrA->arrE.allocatedSizeE < widthA * heightA ) + { + bbs_ERROR0( "void bim_ComplexImage_size( struct bim_ComplexImage*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } + ptrA->widthE = widthA; + ptrA->heightE = heightA; + bbs_ComplexArr_size( cpA, &ptrA->arrE, widthA * heightA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_ComplexImage_memSize( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_ComplexArr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_ComplexImage_memWrite( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_ComplexImage_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_COMPLEX_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + bbs_ComplexArr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_ComplexImage_memRead( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL, widthL, heightL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_COMPLEX_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &widthL, memPtrA ); + memPtrA += bbs_memRead32( &heightL, memPtrA ); + + ptrA->widthE = widthL; + ptrA->heightE = heightL; + bbs_ComplexArr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_ComplexImage_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_ComplexImage_memRead( const struct bim_ComplexImage* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_setAllPixels( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + struct bbs_Complex valueA ) +{ + long iL; + struct bbs_Complex* ptrL = ptrA->arrE.arrPtrE; + for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- ) + { + *ptrL++ = valueA; + } +} + +/* ------------------------------------------------------------------------- */ + +/** + | | | | + | (loop x1) | (loop x2) | (loop x3) | + o------------->-o------------>--o------------->-o + | | | | + | | | | + | | | | + | | | | + ( sectionL->x1E, sectionL->y1E ) | | +---------o- R-------------------------------|---------------- + | | | | | + | | | | | + | | | | | + | | | | | + (loop y1)| | | | + | | | | | + V | | | | + | | |( 0, 0 ) | | X +---------o------------------I-------------------------------------------------> + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + (loop y2)| | | | + | | | | | + | | | | | + | | | | | + V | | | | + | | | | | +---------o------------------|---------------I | + | | | ( srcPtrA->widthE, srcPtrA->heightE ) + | | | | + | | | | + | | | | + | | | | + | | | | + (loop y3)| | | + | | | | + | | | | + V | | | + | | | | +---------o--------------------------------------------------R + | ( sectionL->x2E, sectionL->y2E ) + | + Y | + | + | + V + + To understand how the algorithm work refer to the diagram above. + The image boundaries are indicated by letter "I" ( 0, 0 ) to ( srcPtrA->widthE, srcPtrA->heightE ) + The rectangle boundaries are indicated by letter "R" ( sectionPtrA->x1E, sectionPtrA->y1E ) to ( sectionPtrA->x2E, sectionPtrA->y2E ) + + In the above example the intersection of the image and the rectange is + ( 0, 0 ), ( srcPtrA->widthE, srcPtrA->heightE ) + + The size of the destination image is always ( ( sectionL->x2E, sectionL->y2E ) - ( sectionL->x1E, sectionL->y1E ) ) + + All coordinates are assumed to be relative to the original image. + + 1. parse all pixels in "loop y1" + 1.a. parse all pixels in "loop x1" + 1.b. parse all pixels in "loop x2" + 1.c. parse all pixels in "loop x3" + 2. parse all pixels in "loop y2" + 2.a. parse all pixels in "loop x1" + 2.b. parse all pixels in "loop x2" + 2.c. parse all pixels in "loop x3" + 3. parse all pixels in "loop y3" + 3.a. parse all pixels in "loop x1" + 3.b. parse all pixels in "loop x2" + 3.c. parse all pixels in "loop x3" + +*/ + +/** copies a section of given image */ +void bim_ComplexImage_copySection( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + const struct bim_ComplexImage* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ) +{ + + struct bbs_Complex* srcPixelPtrL; + struct bbs_Complex* dstPixelPtrL; + int32 yIndexL; + int32 xIndexL; + + struct bts_Int16Rect srcImageSubSectionL; + struct bts_Int16Rect sectionL; + + /* make sure that the rectangle passed is correct, in case the x2 < x1 or y2 < y1, swap them */ + sectionL.x1E = bbs_min( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.x2E = bbs_max( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.y1E = bbs_min( sectionPtrA->y1E, sectionPtrA->y2E ); + sectionL.y2E = bbs_max( sectionPtrA->y1E, sectionPtrA->y2E ); + + /* find the intersection betweem the rectangle and the image, the image always starts at 0,0 */ + srcImageSubSectionL.x1E = bbs_max( 0, sectionL.x1E ); + srcImageSubSectionL.y1E = bbs_max( 0, sectionL.y1E ); + srcImageSubSectionL.x2E = bbs_min( ( int32 ) srcPtrA->widthE, sectionL.x2E ); + srcImageSubSectionL.y2E = bbs_min( ( int32 ) srcPtrA->heightE, sectionL.y2E ); + + /* If the image and the rectangle do not intersect in X direction, set the intersecting rectangle to the image coordinates */ + if( srcImageSubSectionL.x2E < srcImageSubSectionL.x1E ) + { + srcImageSubSectionL.x1E = 0; + srcImageSubSectionL.x2E = srcPtrA->widthE; + } + /* do the same as above in the Y direction */ + if( srcImageSubSectionL.y2E < srcImageSubSectionL.y1E ) + { + srcImageSubSectionL.y1E = 0; + srcImageSubSectionL.y2E = srcPtrA->heightE; + } + + /* set size, and allocate required memory for the destination image if required */ + bim_ComplexImage_size( cpA, ptrA, sectionL.x2E - sectionL.x1E, sectionL.y2E - sectionL.y1E ); + + /* get the pointer to the destination image */ + dstPixelPtrL = ptrA->arrE.arrPtrE; + + /* 1. parse all pixels in "loop y1" */ + for( yIndexL = sectionL.y1E; yIndexL < srcImageSubSectionL.y1E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE; + + /* 1.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 1.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 1.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 2. parse all pixels in "loop y2" */ + for( ; yIndexL < srcImageSubSectionL.y2E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE + yIndexL * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 2.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 2.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 2.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 3. parse all pixels in "loop y3" */ + for( ; yIndexL < sectionL.y2E; yIndexL++ ) + { + srcPixelPtrL = srcPtrA->arrE.arrPtrE + ( srcImageSubSectionL.y2E - 1 ) * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 3.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 3.b. parse all pixels in "loop x3" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 3.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + +} + +/* ------------------------------------------------------------------------- */ + +void bim_ComplexImage_importAPh( struct bbs_Context* cpA, + struct bim_ComplexImage* dstPtrA, + const struct bim_APhImage* srcPtrA ) +{ + long iL; + struct bbs_Complex* dstL; + const struct bbs_APh* srcL; + bim_ComplexImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE ); + dstL = dstPtrA->arrE.arrPtrE; + srcL = srcPtrA->arrE.arrPtrE; + for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- ) + { + bbs_Complex_importAPh( dstL++, srcL++ ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/ComplexImage.h b/Embedded/common/src/b_ImageEm/ComplexImage.h new file mode 100644 index 0000000..73cc968 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/ComplexImage.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_COMPLEX_IMAGE_EM_H +#define bim_COMPLEX_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/ComplexArr.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt2D.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bim_APhImage; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_COMPLEX_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** image of complex values */ +struct bim_ComplexImage +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** array of bytes */ + struct bbs_ComplexArr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_ComplexImage */ +void bim_ComplexImage_init( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA ); + +/** frees bim_ComplexImage */ +void bim_ComplexImage_exit( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_ComplexImage_copy( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + const struct bim_ComplexImage* srcPtrA ); + +/** equal operator */ +flag bim_ComplexImage_equal( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA, + const struct bim_ComplexImage* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** checksum of image (for debugging purposes) */ +uint32 bim_ComplexImage_checkSum( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA ); + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bim_ComplexImage_heapSize( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA, + uint32 widthA, uint32 heightA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bim_ComplexImage */ +void bim_ComplexImage_create( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ); + +/** sets image size */ +void bim_ComplexImage_size( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + uint32 widthA, + uint32 heightA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bim_ComplexImage_memSize( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bim_ComplexImage_memWrite( struct bbs_Context* cpA, + const struct bim_ComplexImage* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bim_ComplexImage_memRead( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets all pixels to one value */ +void bim_ComplexImage_setAllPixels( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + struct bbs_Complex valueA ); + +/** copies a section of given image */ +void bim_ComplexImage_copySection( struct bbs_Context* cpA, + struct bim_ComplexImage* ptrA, + const struct bim_ComplexImage* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ); + +/** import abs-phase image */ +void bim_ComplexImage_importAPh( struct bbs_Context* cpA, + struct bim_ComplexImage* dstPtrA, + const struct bim_APhImage* srcPtrA ); + +#endif /* bim_COMPLEX_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/Flt16Image.c b/Embedded/common/src/b_ImageEm/Flt16Image.c new file mode 100644 index 0000000..8e8143b --- /dev/null +++ b/Embedded/common/src/b_ImageEm/Flt16Image.c @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_ImageEm/Flt16Image.h" +#include "b_ImageEm/ComplexImage.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_init( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA ) +{ + bbs_Int16Arr_init( cpA, &ptrA->allocArrE ); + bbs_Int16Arr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_exit( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA ) +{ + bbs_Int16Arr_exit( cpA, &ptrA->arrE ); + bbs_Int16Arr_exit( cpA, &ptrA->allocArrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_copy( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + const struct bim_Flt16Image* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_Flt16Image_copy(...):\n" + "Unsufficient allocated memory in destination image." ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + ptrA->bbpE = srcPtrA->bbpE; + bbs_Int16Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_Flt16Image_equal( struct bbs_Context* cpA, + const struct bim_Flt16Image* ptrA, + const struct bim_Flt16Image* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + if( ptrA->bbpE != srcPtrA->bbpE ) return FALSE; + return bbs_Int16Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_create( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_Flt16Image_size( cpA, ptrA, widthA, heightA ); + } + else + { + /* OLD CODE + bbs_Int16Arr_create( cpA, &ptrA->arrE, widthA * heightA, mspA ); + */ + bbs_Int16Arr_createAligned( cpA, &ptrA->arrE, widthA * heightA, mspA, &ptrA->allocArrE, bbs_MEMORY_ALIGNMENT ); + + ptrA->widthE = widthA; + ptrA->heightE = heightA; + } +} + +/* ------------------------------------------------------------------------- */ +/* incompatible with ALIGN +void bim_Flt16Image_assignExternalImage( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + struct bim_Flt16Image* srcPtrA ) +{ + struct bbs_MemSeg sharedSegL = bbs_MemSeg_createShared( cpA, srcPtrA->arrE.arrPtrE, srcPtrA->widthE * srcPtrA->heightE ); + + if( ptrA->arrE.arrPtrE != 0 ) + { + bbs_ERROR0( "void bim_Flt16Image_assignExternalImage( ... ): image was already created once" ); + return; + } + + bim_Flt16Image_create( cpA, + ptrA, + srcPtrA->widthE, + srcPtrA->heightE, + &sharedSegL ); + + ptrA->bbpE = srcPtrA->bbpE; +} +*/ +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_size( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + uint32 widthA, + uint32 heightA ) +{ + if( ptrA->arrE.allocatedSizeE < widthA * heightA ) + { + bbs_ERROR0( "void bim_Flt16Image_size( struct bim_Flt16Image*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } + ptrA->widthE = widthA; + ptrA->heightE = heightA; + bbs_Int16Arr_size( cpA, &ptrA->arrE, widthA * heightA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_Flt16Image_memSize( struct bbs_Context* cpA, + const struct bim_Flt16Image* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_SIZEOF16( ptrA->bbpE ) + + bbs_Int16Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_Flt16Image_memWrite( struct bbs_Context* cpA, + const struct bim_Flt16Image* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_Flt16Image_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_FLT16_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->bbpE, memPtrA ); + bbs_Int16Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_Flt16Image_memRead( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_FLT16_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->heightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->bbpE, memPtrA ); + bbs_Int16Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_Flt16Image_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_Flt16Image_memRead( const struct bim_Flt16Image* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_setAllPixels( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + int16 valueA, + int32 bbpA ) +{ + long iL; + int16* ptrL = ptrA->arrE.arrPtrE; + for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- ) + { + *ptrL++ = valueA; + } + ptrA->bbpE = bbpA; +} + +/* ------------------------------------------------------------------------- */ + +/** + | | | | + | (loop x1) | (loop x2) | (loop x3) | + o------------->-o------------>--o------------->-o + | | | | + | | | | + | | | | + | | | | + ( sectionL->x1E, sectionL->y1E ) | | +---------o- R-------------------------------|---------------- + | | | | | + | | | | | + | | | | | + | | | | | + (loop y1)| | | | + | | | | | + V | | | | + | | |( 0, 0 ) | | X +---------o------------------I-------------------------------------------------> + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + (loop y2)| | | | + | | | | | + | | | | | + | | | | | + V | | | | + | | | | | +---------o------------------|---------------I | + | | | ( srcPtrA->widthE, srcPtrA->heightE ) + | | | | + | | | | + | | | | + | | | | + | | | | + (loop y3)| | | + | | | | + | | | | + V | | | + | | | | +---------o--------------------------------------------------R + | ( sectionL->x2E, sectionL->y2E ) + | + Y | + | + | + V + + To understand how the algorithm work refer to the diagram above. + The image boundaries are indicated by letter "I" ( 0, 0 ) to ( srcPtrA->widthE, srcPtrA->heightE ) + The rectangle boundaries are indicated by letter "R" ( sectionPtrA->x1E, sectionPtrA->y1E ) to ( sectionPtrA->x2E, sectionPtrA->y2E ) + + In the above example the intersection of the image and the rectange is + ( 0, 0 ), ( srcPtrA->widthE, srcPtrA->heightE ) + + The size of the destination image is always ( ( sectionL->x2E, sectionL->y2E ) - ( sectionL->x1E, sectionL->y1E ) ) + + All coordinates are assumed to be relative to the original image. + + 1. parse all pixels in "loop y1" + 1.a. parse all pixels in "loop x1" + 1.b. parse all pixels in "loop x2" + 1.c. parse all pixels in "loop x3" + 2. parse all pixels in "loop y2" + 2.a. parse all pixels in "loop x1" + 2.b. parse all pixels in "loop x2" + 2.c. parse all pixels in "loop x3" + 3. parse all pixels in "loop y3" + 3.a. parse all pixels in "loop x1" + 3.b. parse all pixels in "loop x2" + 3.c. parse all pixels in "loop x3" + +*/ + +/** copies a section of given image */ +void bim_Flt16Image_copySection( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + const struct bim_Flt16Image* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ) +{ + + int16* srcPixelPtrL; + int16* dstPixelPtrL; + int32 yIndexL; + int32 xIndexL; + + struct bts_Int16Rect srcImageSubSectionL; + struct bts_Int16Rect sectionL; + + /* make sure that the rectangle passed is correct, in case the x2 < x1 or y2 < y1, swap them */ + sectionL.x1E = bbs_min( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.x2E = bbs_max( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.y1E = bbs_min( sectionPtrA->y1E, sectionPtrA->y2E ); + sectionL.y2E = bbs_max( sectionPtrA->y1E, sectionPtrA->y2E ); + + /* find the intersection betweem the rectangle and the image, the image always starts at 0,0 */ + srcImageSubSectionL.x1E = bbs_max( 0, sectionL.x1E ); + srcImageSubSectionL.y1E = bbs_max( 0, sectionL.y1E ); + srcImageSubSectionL.x2E = bbs_min( ( int32 ) srcPtrA->widthE, sectionL.x2E ); + srcImageSubSectionL.y2E = bbs_min( ( int32 ) srcPtrA->heightE, sectionL.y2E ); + + /* If the image and the rectangle do not intersect in X direction, set the intersecting rectangle to the image coordinates */ + if( srcImageSubSectionL.x2E < srcImageSubSectionL.x1E ) + { + srcImageSubSectionL.x1E = 0; + srcImageSubSectionL.x2E = srcPtrA->widthE; + } + /* do the same as above in the Y direction */ + if( srcImageSubSectionL.y2E < srcImageSubSectionL.y1E ) + { + srcImageSubSectionL.y1E = 0; + srcImageSubSectionL.y2E = srcPtrA->heightE; + } + + /* initialize, set size, and allocate required memory for the destination image if required */ + bim_Flt16Image_size( cpA, ptrA, sectionL.x2E - sectionL.x1E, sectionL.y2E - sectionL.y1E ); + ptrA->bbpE = srcPtrA->bbpE; + + /* get the pointer to the destination image */ + dstPixelPtrL = ptrA->arrE.arrPtrE; + + /* 1. parse all pixels in "loop y1" */ + for( yIndexL = sectionL.y1E; yIndexL < srcImageSubSectionL.y1E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE; + + /* 1.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 1.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 1.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 2. parse all pixels in "loop y2" */ + for( ; yIndexL < srcImageSubSectionL.y2E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE + yIndexL * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 2.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 2.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 2.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 3. parse all pixels in "loop y3" */ + for( ; yIndexL < sectionL.y2E; yIndexL++ ) + { + srcPixelPtrL = srcPtrA->arrE.arrPtrE + ( srcImageSubSectionL.y2E - 1 ) * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 3.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 3.b. parse all pixels in "loop x3" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 3.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + +} + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_importReal( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ) +{ + long iL; + int16* dstL; + const struct bbs_Complex* srcL; + bim_Flt16Image_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE ); + dstPtrA->bbpE = 0; + dstL = dstPtrA->arrE.arrPtrE; + srcL = srcPtrA->arrE.arrPtrE; + for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- ) + { + *dstL++ = ( *srcL++ ).realE; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_importImag( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ) +{ + long iL; + int16* dstL; + const struct bbs_Complex* srcL; + bim_Flt16Image_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE ); + dstPtrA->bbpE = 0; + dstL = dstPtrA->arrE.arrPtrE; + srcL = srcPtrA->arrE.arrPtrE; + for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- ) + { + *dstL++ = ( *srcL++ ).imagE; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_importAbs( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ) +{ + long iL; + int16* dstL; + const struct bbs_Complex* srcL; + bim_Flt16Image_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE ); + dstPtrA->bbpE = 0; + dstL = dstPtrA->arrE.arrPtrE; + srcL = srcPtrA->arrE.arrPtrE; + for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- ) + { + *dstL++ = bbs_sqrt32( ( int32 )srcL->realE * srcL->realE + ( int32 )srcL->imagE * srcL->imagE ); + srcL++; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_Flt16Image_importPhase( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ) +{ + long iL; + int16* dstL; + const struct bbs_Complex* srcL; + bim_Flt16Image_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE ); + dstPtrA->bbpE = 0; + dstL = dstPtrA->arrE.arrPtrE; + srcL = srcPtrA->arrE.arrPtrE; + for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- ) + { + *dstL++ = bbs_phase16( srcL->realE, srcL->imagE ); + srcL++; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/Flt16Image.h b/Embedded/common/src/b_ImageEm/Flt16Image.h new file mode 100644 index 0000000..875b636 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/Flt16Image.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_FLT16_IMAGE_EM_H +#define bim_FLT16_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt2D.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bim_ComplexImage; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_FLT16_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** image of int16 with floating point */ +struct bim_Flt16Image +{ + + /* ---- private data --------------------------------------------------- */ + + /** allocated array of bytes */ + struct bbs_Int16Arr allocArrE; + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** point position */ + int32 bbpE; + + /** array of bytes */ + struct bbs_Int16Arr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_Flt16Image */ +void bim_Flt16Image_init( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA ); + +/** destroys bim_Flt16Image */ +void bim_Flt16Image_exit( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_Flt16Image_copy( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + const struct bim_Flt16Image* srcPtrA ); + +/** equal operator */ +flag bim_Flt16Image_equal( struct bbs_Context* cpA, + const struct bim_Flt16Image* ptrA, + const struct bim_Flt16Image* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bim_Flt16Image */ +void bim_Flt16Image_create( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ); + +/** assigns external image to array (no allocation, deallocation or copying of data) */ +/*void bim_Flt16Image_assignExternalImage( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + struct bim_Flt16Image* srcPtrA ); +*/ +/** sets image size */ +void bim_Flt16Image_size( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + uint32 widthA, + uint32 heightA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) needs when written to memory */ +uint32 bim_Flt16Image_memSize( struct bbs_Context* cpA, + const struct bim_Flt16Image* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bim_Flt16Image_memWrite( struct bbs_Context* cpA, + const struct bim_Flt16Image* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bim_Flt16Image_memRead( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets all pixels to one value */ +void bim_Flt16Image_setAllPixels( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + int16 valueA, int32 bbpA ); + +/** copies a section of given image */ +void bim_Flt16Image_copySection( struct bbs_Context* cpA, + struct bim_Flt16Image* ptrA, + const struct bim_Flt16Image* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ); + +/** imports real values from complex image */ +void bim_Flt16Image_importReal( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ); + +/** imports imaginary values from complex image */ +void bim_Flt16Image_importImag( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ); + +/** imports magnitudes from complex image */ +void bim_Flt16Image_importAbs( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ); + +/** imports phases from complex image */ +void bim_Flt16Image_importPhase( struct bbs_Context* cpA, + struct bim_Flt16Image* dstPtrA, + const struct bim_ComplexImage* srcPtrA ); + + +#endif /* bim_FLT16_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/Functions.c b/Embedded/common/src/b_ImageEm/Functions.c new file mode 100644 index 0000000..c99540e --- /dev/null +++ b/Embedded/common/src/b_ImageEm/Functions.c @@ -0,0 +1,734 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_ImageEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/** downscale by factor 2 (dstPtrA and srcPtrA may be identical) */ +void bim_downscaleBy2( uint8* dstPtrA, + const uint8* srcPtrA, + uint32 srcWidthA, + uint32 effWidthA, + uint32 effHeightA ) +{ + uint32 wsL = srcWidthA; + uint32 w0L = effWidthA; + uint32 h0L = effHeightA; + uint32 w1L = w0L >> 1; + uint32 h1L = h0L >> 1; + + const uint8* srcL = srcPtrA; + uint8* dstL = dstPtrA; + + uint32 iL, jL; + for( jL = 0; jL < h1L; jL++ ) + { + for( iL = 0; iL < w1L; iL++ ) + { + *dstL = ( ( uint32 )srcL[ 0 ] + srcL[ 1 ] + srcL[ wsL ] + srcL[ wsL + 1 ] + 2 ) >> 2; + dstL++; + srcL += 2; + } + srcL += ( wsL - w1L ) * 2; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_filterWarpInterpolation( struct bbs_Context* cpA, + uint8* dstImagePtrA, + const uint8* srcImagePtrA, + uint32 srcImageWidthA, + uint32 srcImageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_Flt16Alt2D* altPtrA, + uint32 dstWidthA, + uint32 dstHeightA, + struct bbs_UInt8Arr* bufPtrA, + uint32 scaleThresholdA ) +{ + bbs_DEF_fNameL( "bim_filterWarpInterpolation" ) + + uint32 w0L = srcImageWidthA; + uint32 h0L = srcImageHeightA; + + const uint8* srcL = srcImagePtrA; + uint8* dstL = dstImagePtrA; + + uint32 w1L = w0L; + uint32 h1L = h0L; + + /* 16.16 */ + uint32 scaleThrL = scaleThresholdA; + struct bts_Flt16Alt2D invAltL; + + /* matrix variables */ + int32 mxxL, mxyL, myxL, myyL, txL, tyL; + + flag downScaledL = FALSE; + flag boundsOkL = TRUE; + + if( w0L == 0 || h0L == 0 || bts_Flt16Mat2D_det( &altPtrA->matE ) == 0 ) + { + uint32 iL; + for( iL = 0; iL < dstWidthA * dstHeightA; iL++ ) dstImagePtrA[ iL ] = 0; + return; + } + + /* compute inverse ALT */ + invAltL = bts_Flt16Alt2D_inverted( altPtrA ); + + /* fixed point ALT 16.16 */ + if( invAltL.matE.bbpE <= 16 ) + { + uint32 shlL = 16 - invAltL.matE.bbpE; + mxxL = invAltL.matE.xxE << shlL; + mxyL = invAltL.matE.xyE << shlL; + myxL = invAltL.matE.yxE << shlL; + myyL = invAltL.matE.yyE << shlL; + } + else + { + uint32 shrL = invAltL.matE.bbpE - 16; + mxxL = ( ( invAltL.matE.xxE >> ( shrL - 1 ) ) + 1 ) >> 1; + mxyL = ( ( invAltL.matE.xyE >> ( shrL - 1 ) ) + 1 ) >> 1; + myxL = ( ( invAltL.matE.yxE >> ( shrL - 1 ) ) + 1 ) >> 1; + myyL = ( ( invAltL.matE.yyE >> ( shrL - 1 ) ) + 1 ) >> 1; + } + + if( invAltL.vecE.bbpE <= 16 ) + { + uint32 shlL = 16 - invAltL.vecE.bbpE; + txL = invAltL.vecE.xE << shlL; + tyL = invAltL.vecE.yE << shlL; + } + else + { + uint32 shrL = invAltL.vecE.bbpE - 16; + txL = ( ( invAltL.vecE.xE >> ( shrL - 1 ) ) + 1 ) >> 1; + tyL = ( ( invAltL.vecE.yE >> ( shrL - 1 ) ) + 1 ) >> 1; + } + + /* add offset */ + txL += ( int32 )offsPtrA->xE << 16; + tyL += ( int32 )offsPtrA->yE << 16; + + if( scaleThresholdA > 0 ) + { + /* compute downscale exponent */ + uint32 axxL = ( mxxL >= 0 ) ? mxxL : -mxxL; + uint32 axyL = ( mxyL >= 0 ) ? mxyL : -mxyL; + uint32 ayxL = ( myxL >= 0 ) ? myxL : -myxL; + uint32 ayyL = ( myyL >= 0 ) ? myyL : -myyL; + + uint32 a1L = ( axxL > ayxL ) ? axxL : ayxL; + uint32 a2L = ( axyL > ayyL ) ? axyL : ayyL; + + uint32 invScaleL = ( a1L < a2L ) ? a1L : a2L; + uint32 scaleExpL = 0; + while( ( invScaleL >> scaleExpL ) > scaleThrL ) scaleExpL++; + while( ( scaleExpL > 0 ) && ( w0L >> scaleExpL ) < 2 ) scaleExpL--; + while( ( scaleExpL > 0 ) && ( h0L >> scaleExpL ) < 2 ) scaleExpL--; + + /* downscale image */ + if( scaleExpL > 0 ) + { + /* down sampling is limited to the effective area of the original image */ + + /* compute effective area by mapping all corners of the dst rectangle */ + int32 xMinL = 0x7FFFFFFF; + int32 yMinL = 0x7FFFFFFF; + int32 xMaxL = 0x80000000; + int32 yMaxL = 0x80000000; + uint32 wEffL, hEffL; + + { + int32 xL, yL; + xL = txL; + yL = tyL; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + xL = txL + mxxL * ( int32 )dstWidthA + mxyL * ( int32 )dstHeightA; + yL = tyL + myxL * ( int32 )dstWidthA + myyL * ( int32 )dstHeightA; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + xL = txL + mxyL * ( int32 )dstHeightA; + yL = tyL + myyL * ( int32 )dstHeightA; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + xL = txL + mxxL * ( int32 )dstWidthA; + yL = tyL + myxL * ( int32 )dstWidthA; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + } + + xMaxL = ( xMaxL >> 16 ) + 2; + yMaxL = ( yMaxL >> 16 ) + 2; + xMinL >>= 16; + yMinL >>= 16; + + /* ensre effective area stays within original frame */ + xMinL = 0 > xMinL ? 0 : xMinL; + yMinL = 0 > yMinL ? 0 : yMinL; + xMinL = ( int32 )w0L < xMinL ? w0L : xMinL; + yMinL = ( int32 )h0L < yMinL ? h0L : yMinL; + xMaxL = 0 > xMaxL ? 0 : xMaxL; + yMaxL = 0 > yMaxL ? 0 : yMaxL; + xMaxL = ( int32 )w0L < xMaxL ? w0L : xMaxL; + yMaxL = ( int32 )h0L < yMaxL ? h0L : yMaxL; + + wEffL = xMaxL - xMinL; + hEffL = yMaxL - yMinL; + + /* ensure downscaling does not reduce image to 0 */ + while( ( scaleExpL > 0 ) && ( wEffL >> scaleExpL ) < 2 ) scaleExpL--; + while( ( scaleExpL > 0 ) && ( hEffL >> scaleExpL ) < 2 ) scaleExpL--; + + /* downscale */ + if( scaleExpL > 0 ) + { + uint32 iL; + w1L = wEffL >> 1; + h1L = hEffL >> 1; + if( bufPtrA == NULL ) bbs_ERROR1( "%s:\nPreallocated buffer is needed", fNameL ); + bbs_UInt8Arr_size( cpA, bufPtrA, w1L * h1L ); + bim_downscaleBy2( bufPtrA->arrPtrE, srcL + yMinL * w0L + xMinL, w0L, wEffL, hEffL ); + for( iL = 1; iL < scaleExpL; iL++ ) + { + bim_downscaleBy2( bufPtrA->arrPtrE, bufPtrA->arrPtrE, w1L, w1L, h1L ); + w1L >>= 1; + h1L >>= 1; + } + + /* adjust inverted cordinates */ + txL -= ( xMinL << 16 ); + tyL -= ( yMinL << 16 ); + mxxL >>= scaleExpL; + mxyL >>= scaleExpL; + myxL >>= scaleExpL; + myyL >>= scaleExpL; + txL >>= scaleExpL; + tyL >>= scaleExpL; + srcL = bufPtrA->arrPtrE; + } + + downScaledL = TRUE; + } + } + + /* if not downscaled and src and dst images are identcal then copy srcImage into buffer */ + if( !downScaledL && dstImagePtrA == srcImagePtrA ) + { + uint32 iL; + uint32 srcSizeL = srcImageWidthA * srcImageHeightA; + if( bufPtrA == NULL ) bbs_ERROR1( "%s:\nPreallocated buffer is needed", fNameL ); + bbs_UInt8Arr_size( cpA, bufPtrA, srcSizeL ); + for( iL = 0; iL < srcSizeL; iL++ ) bufPtrA->arrPtrE[ iL ] = srcImagePtrA[ iL ]; + srcL = bufPtrA->arrPtrE; + } + + /* compute destination image */ + + /* bounds check (dst image fully inside src image? -> fast algorithm) */ + { + int32 xL, yL; + int32 wbL = w1L - 1; + int32 hbL = h1L - 1; + + xL = txL >> 16; + yL = tyL >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + + xL = ( txL + mxxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + yL = ( tyL + myxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + + xL = ( txL + mxyL * ( int32 )( dstHeightA - 1 ) ) >> 16; + yL = ( tyL + myyL * ( int32 )( dstHeightA - 1 ) ) >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + + xL = ( txL + mxyL * ( int32 )( dstHeightA - 1 ) + mxxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + yL = ( tyL + myyL * ( int32 )( dstHeightA - 1 ) + myxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + } + + if( boundsOkL ) + { + int32 iL, jL; + for( jL = 0; jL < ( int32 )dstHeightA; jL++ ) + { + /* 16.16 */ + int32 xL = txL + mxyL * jL; + int32 yL = tyL + myyL * jL; + for( iL = 0; iL < ( int32 )dstWidthA; iL++ ) + { + int32 x0L = xL >> 16; + int32 y0L = yL >> 16; + uint32 xf2L = xL & 0x0FFFF; + uint32 yf2L = yL & 0x0FFFF; + uint32 xf1L = 0x10000 - xf2L; + uint32 yf1L = 0x10000 - yf2L; + + xL += mxxL; + yL += myxL; + + { + uint32 idxL = y0L * w1L + x0L; + uint32 v1L = ( ( uint32 )srcL[ idxL ] * xf1L + ( uint32 )srcL[ idxL + 1 ] * xf2L + 0x0800 ) >> 12; + uint32 v2L = ( ( uint32 )srcL[ idxL + w1L ] * xf1L + ( uint32 )srcL[ idxL + w1L + 1 ] * xf2L + 0x0800 ) >> 12; + *dstL++ = ( v1L * yf1L + v2L * yf2L + 0x080000 ) >> 20; + } + } + } + } + else + { + int32 iL, jL; + for( jL = 0; jL < ( int32 )dstHeightA; jL++ ) + { + /* 16.16 */ + int32 xL = txL + mxyL * jL; + int32 yL = tyL + myyL * jL; + for( iL = 0; iL < ( int32 )dstWidthA; iL++ ) + { + int32 x0L = xL >> 16; + int32 y0L = yL >> 16; + uint32 xf2L = xL & 0x0FFFF; + uint32 yf2L = yL & 0x0FFFF; + uint32 xf1L = 0x10000 - xf2L; + uint32 yf1L = 0x10000 - yf2L; + + xL += mxxL; + yL += myxL; + + if( y0L < 0 ) + { + if( x0L < 0 ) + { + *dstL++ = srcL[ 0 ]; + } + else if( x0L >= ( int32 )w1L - 1 ) + { + *dstL++ = srcL[ w1L - 1 ]; + } + else + { + *dstL++ = ( ( uint32 )srcL[ x0L ] * xf1L + ( uint32 )srcL[ x0L + 1 ] * xf2L + 0x08000 ) >> 16; + } + } + else if( y0L >= ( int32 )h1L - 1 ) + { + if( x0L < 0 ) + { + *dstL++ = srcL[ ( h1L - 1 ) * w1L ]; + } + else if( x0L >= ( int32 )w1L - 1 ) + { + *dstL++ = srcL[ ( h1L * w1L ) - 1 ]; + } + else + { + uint32 idxL = ( h1L - 1 ) * w1L + x0L; + *dstL++ = ( ( uint32 )srcL[ idxL ] * xf1L + ( uint32 )srcL[ idxL + 1 ] * xf2L + 0x08000 ) >> 16; + } + } + else + { + if( x0L < 0 ) + { + uint32 idxL = y0L * w1L; + *dstL++ = ( ( uint32 )srcL[ idxL ] * yf1L + ( uint32 )srcL[ idxL + w1L ] * yf2L + 0x08000 ) >> 16; + } + else if( x0L >= ( int32 )w1L - 1 ) + { + uint32 idxL = ( y0L + 1 ) * w1L - 1; + *dstL++ = ( ( uint32 )srcL[ idxL ] * yf1L + ( uint32 )srcL[ idxL + w1L ] * yf2L + 0x08000 ) >> 16; + } + else + { + uint32 idxL = y0L * w1L + x0L; + uint32 v1L = ( ( uint32 )srcL[ idxL ] * xf1L + ( uint32 )srcL[ idxL + 1 ] * xf2L + 0x0800 ) >> 12; + uint32 v2L = ( ( uint32 )srcL[ idxL + w1L ] * xf1L + ( uint32 )srcL[ idxL + w1L + 1 ] * xf2L + 0x0800 ) >> 12; + *dstL++ = ( v1L * yf1L + v2L * yf2L + 0x080000 ) >> 20; + } + } + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_filterWarpPixelReplication( struct bbs_Context* cpA, + uint8* dstImagePtrA, + const uint8* srcImagePtrA, + uint32 srcImageWidthA, + uint32 srcImageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_Flt16Alt2D* altPtrA, + uint32 dstWidthA, + uint32 dstHeightA, + struct bbs_UInt8Arr* bufPtrA, + uint32 scaleThresholdA ) +{ + bbs_DEF_fNameL( "bim_filterWarpPixelReplication" ) + + uint32 w0L = srcImageWidthA; + uint32 h0L = srcImageHeightA; + + const uint8* srcL = srcImagePtrA; + uint8* dstL = dstImagePtrA; + + uint32 w1L = w0L; + uint32 h1L = h0L; + + /* 16.16 */ + uint32 scaleThrL = scaleThresholdA; + struct bts_Flt16Alt2D invAltL; + + /* matrix variables */ + int32 mxxL, mxyL, myxL, myyL, txL, tyL; + + flag downScaledL = FALSE; + flag boundsOkL = TRUE; + + if( w0L == 0 || h0L == 0 || bts_Flt16Mat2D_det( &altPtrA->matE ) == 0 ) + { + uint32 iL; + for( iL = 0; iL < dstWidthA * dstHeightA; iL++ ) dstImagePtrA[ iL ] = 0; + return; + } + + /* compute inverse ALT */ + invAltL = bts_Flt16Alt2D_inverted( altPtrA ); + + /* fixed point ALT 16.16 */ + if( invAltL.matE.bbpE <= 16 ) + { + uint32 shlL = 16 - invAltL.matE.bbpE; + mxxL = invAltL.matE.xxE << shlL; + mxyL = invAltL.matE.xyE << shlL; + myxL = invAltL.matE.yxE << shlL; + myyL = invAltL.matE.yyE << shlL; + } + else + { + uint32 shrL = invAltL.matE.bbpE - 16; + mxxL = ( ( invAltL.matE.xxE >> ( shrL - 1 ) ) + 1 ) >> 1; + mxyL = ( ( invAltL.matE.xyE >> ( shrL - 1 ) ) + 1 ) >> 1; + myxL = ( ( invAltL.matE.yxE >> ( shrL - 1 ) ) + 1 ) >> 1; + myyL = ( ( invAltL.matE.yyE >> ( shrL - 1 ) ) + 1 ) >> 1; + } + + if( invAltL.vecE.bbpE <= 16 ) + { + uint32 shlL = 16 - invAltL.vecE.bbpE; + txL = invAltL.vecE.xE << shlL; + tyL = invAltL.vecE.yE << shlL; + } + else + { + uint32 shrL = invAltL.vecE.bbpE - 16; + txL = ( ( invAltL.vecE.xE >> ( shrL - 1 ) ) + 1 ) >> 1; + tyL = ( ( invAltL.vecE.yE >> ( shrL - 1 ) ) + 1 ) >> 1; + } + + /* add offset */ + txL += ( int32 )offsPtrA->xE << 16; + tyL += ( int32 )offsPtrA->yE << 16; + + if( scaleThresholdA > 0 ) + { + /* compute downscale exponent */ + uint32 axxL = ( mxxL >= 0 ) ? mxxL : -mxxL; + uint32 axyL = ( mxyL >= 0 ) ? mxyL : -mxyL; + uint32 ayxL = ( myxL >= 0 ) ? myxL : -myxL; + uint32 ayyL = ( myyL >= 0 ) ? myyL : -myyL; + + uint32 a1L = ( axxL > ayxL ) ? axxL : ayxL; + uint32 a2L = ( axyL > ayyL ) ? axyL : ayyL; + + uint32 invScaleL = ( a1L < a2L ) ? a1L : a2L; + uint32 scaleExpL = 0; + while( ( invScaleL >> scaleExpL ) > scaleThrL ) scaleExpL++; + while( ( scaleExpL > 0 ) && ( w0L >> scaleExpL ) < 2 ) scaleExpL--; + while( ( scaleExpL > 0 ) && ( h0L >> scaleExpL ) < 2 ) scaleExpL--; + + /* downscale image */ + if( scaleExpL > 0 ) + { + /* down sampling is limited to the effective area of the original image */ + + /* compute effective area by mapping all corners of the dst rectangle */ + int32 xMinL = 0x7FFFFFFF; + int32 yMinL = 0x7FFFFFFF; + int32 xMaxL = 0x80000000; + int32 yMaxL = 0x80000000; + uint32 wEffL, hEffL; + + { + int32 xL, yL; + xL = txL; + yL = tyL; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + xL = txL + mxxL * ( int32 )dstWidthA + mxyL * ( int32 )dstHeightA; + yL = tyL + myxL * ( int32 )dstWidthA + myyL * ( int32 )dstHeightA; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + xL = txL + mxyL * ( int32 )dstHeightA; + yL = tyL + myyL * ( int32 )dstHeightA; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + xL = txL + mxxL * ( int32 )dstWidthA; + yL = tyL + myxL * ( int32 )dstWidthA; + xMinL = xL < xMinL ? xL : xMinL; + yMinL = yL < yMinL ? yL : yMinL; + xMaxL = xL > xMaxL ? xL : xMaxL; + yMaxL = yL > yMaxL ? yL : yMaxL; + } + + xMaxL = ( xMaxL >> 16 ) + 2; + yMaxL = ( yMaxL >> 16 ) + 2; + xMinL >>= 16; + yMinL >>= 16; + + /* ensre effective area stays within original frame */ + xMinL = 0 > xMinL ? 0 : xMinL; + yMinL = 0 > yMinL ? 0 : yMinL; + xMinL = ( int32 )w0L < xMinL ? w0L : xMinL; + yMinL = ( int32 )h0L < yMinL ? h0L : yMinL; + xMaxL = 0 > xMaxL ? 0 : xMaxL; + yMaxL = 0 > yMaxL ? 0 : yMaxL; + xMaxL = ( int32 )w0L < xMaxL ? w0L : xMaxL; + yMaxL = ( int32 )h0L < yMaxL ? h0L : yMaxL; + + wEffL = xMaxL - xMinL; + hEffL = yMaxL - yMinL; + + /* ensure downscaling does not reduce image to 0 */ + while( ( scaleExpL > 0 ) && ( wEffL >> scaleExpL ) < 2 ) scaleExpL--; + while( ( scaleExpL > 0 ) && ( hEffL >> scaleExpL ) < 2 ) scaleExpL--; + + /* downscale */ + if( scaleExpL > 0 ) + { + uint32 iL; + w1L = wEffL >> 1; + h1L = hEffL >> 1; + if( bufPtrA == NULL ) bbs_ERROR1( "%s:\nPreallocated buffer is needed", fNameL ); + bbs_UInt8Arr_size( cpA, bufPtrA, w1L * h1L ); + bim_downscaleBy2( bufPtrA->arrPtrE, srcL + yMinL * w0L + xMinL, w0L, wEffL, hEffL ); + for( iL = 1; iL < scaleExpL; iL++ ) + { + bim_downscaleBy2( bufPtrA->arrPtrE, bufPtrA->arrPtrE, w1L, w1L, h1L ); + w1L >>= 1; + h1L >>= 1; + } + + /* adjust inverted cordinates */ + txL -= ( xMinL << 16 ); + tyL -= ( yMinL << 16 ); + mxxL >>= scaleExpL; + mxyL >>= scaleExpL; + myxL >>= scaleExpL; + myyL >>= scaleExpL; + txL >>= scaleExpL; + tyL >>= scaleExpL; + srcL = bufPtrA->arrPtrE; + } + + downScaledL = TRUE; + } + } + + /* if not downscaled and src and dst images are identcal then copy srcImage into buffer */ + if( !downScaledL && dstImagePtrA == srcImagePtrA ) + { + uint32 iL; + uint32 srcSizeL = srcImageWidthA * srcImageHeightA; + if( bufPtrA == NULL ) bbs_ERROR1( "%s:\nPreallocated buffer is needed", fNameL ); + bbs_UInt8Arr_size( cpA, bufPtrA, srcSizeL ); + for( iL = 0; iL < srcSizeL; iL++ ) bufPtrA->arrPtrE[ iL ] = srcImagePtrA[ iL ]; + srcL = bufPtrA->arrPtrE; + } + + /* compute destination image */ + + /* bounds check (dst image fully inside src image? -> fast algorithm) */ + { + int32 xL, yL; + int32 wbL = w1L - 1; + int32 hbL = h1L - 1; + + xL = txL >> 16; + yL = tyL >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + + xL = ( txL + mxxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + yL = ( tyL + myxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + + xL = ( txL + mxyL * ( int32 )( dstHeightA - 1 ) ) >> 16; + yL = ( tyL + myyL * ( int32 )( dstHeightA - 1 ) ) >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + + xL = ( txL + mxyL * ( int32 )( dstHeightA - 1 ) + mxxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + yL = ( tyL + myyL * ( int32 )( dstHeightA - 1 ) + myxL * ( int32 )( dstWidthA - 1 ) ) >> 16; + boundsOkL = boundsOkL && ( xL >= 0 && xL < wbL && yL >= 0 && yL < hbL ); + } + + if( boundsOkL ) + { + int32 iL, jL; + for( jL = 0; jL < ( int32 )dstHeightA; jL++ ) + { + /* 16.16 */ + int32 xL = txL + mxyL * jL; + int32 yL = tyL + myyL * jL; + for( iL = 0; iL < ( int32 )dstWidthA; iL++ ) + { + /* nearest whole position */ + *dstL++ = srcL[ ( ( ( yL >> 15 ) + 1 ) >> 1 ) * w1L + ( ( ( xL >> 15 ) + 1 ) >> 1 ) ]; + xL += mxxL; + yL += myxL; + } + } + } + else + { + int32 iL, jL; + for( jL = 0; jL < ( int32 )dstHeightA; jL++ ) + { + /* 16.16 */ + int32 xL = txL + mxyL * jL; + int32 yL = tyL + myyL * jL; + for( iL = 0; iL < ( int32 )dstWidthA; iL++ ) + { + /* nearest whole position */ + int32 x0L = ( ( xL >> 15 ) + 1 ) >> 1; + int32 y0L = ( ( yL >> 15 ) + 1 ) >> 1; + xL += mxxL; + yL += myxL; + + if( y0L < 0 ) + { + if( x0L < 0 ) + { + *dstL++ = srcL[ 0 ]; + } + else if( x0L >= ( int32 )w1L - 1 ) + { + *dstL++ = srcL[ w1L - 1 ]; + } + else + { + *dstL++ = srcL[ x0L ]; + } + } + else if( y0L >= ( int32 )h1L - 1 ) + { + if( x0L < 0 ) + { + *dstL++ = srcL[ ( h1L - 1 ) * w1L ]; + } + else if( x0L >= ( int32 )w1L - 1 ) + { + *dstL++ = srcL[ ( h1L * w1L ) - 1 ]; + } + else + { + *dstL++ = srcL[ ( h1L - 1 ) * w1L + x0L ]; + } + } + else + { + if( x0L < 0 ) + { + *dstL++ = srcL[ y0L * w1L ]; + } + else if( x0L >= ( int32 )w1L - 1 ) + { + *dstL++ = srcL[ ( y0L + 1 ) * w1L - 1 ]; + } + else + { + *dstL++ = srcL[ y0L * w1L + x0L ]; + } + } + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_filterWarp( struct bbs_Context* cpA, + uint8* dstImagePtrA, + const uint8* srcImagePtrA, + uint32 srcImageWidthA, + uint32 srcImageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_Flt16Alt2D* altPtrA, + uint32 dstWidthA, + uint32 dstHeightA, + struct bbs_UInt8Arr* bufPtrA, + uint32 scaleThresholdA, + flag interpolateA ) +{ + if( interpolateA ) + { + bim_filterWarpInterpolation( cpA, dstImagePtrA, srcImagePtrA, srcImageWidthA, srcImageHeightA, offsPtrA, altPtrA, dstWidthA, dstHeightA, bufPtrA, scaleThresholdA ); + } + else + { + bim_filterWarpPixelReplication( cpA, dstImagePtrA, srcImagePtrA, srcImageWidthA, srcImageHeightA, offsPtrA, altPtrA, dstWidthA, dstHeightA, bufPtrA, scaleThresholdA ); + } +} + +/* ------------------------------------------------------------------------- */ + diff --git a/Embedded/common/src/b_ImageEm/Functions.h b/Embedded/common/src/b_ImageEm/Functions.h new file mode 100644 index 0000000..ff272eb --- /dev/null +++ b/Embedded/common/src/b_ImageEm/Functions.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_FUNCTIONS_EM_H +#define bim_FUNCTIONS_EM_H + +/** + * This files contains gerenral purpose functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/UInt8Arr.h" +#include "b_TensorEm/Functions.h" +#include "b_TensorEm/Flt16Alt2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** pyramidal image type */ +enum bim_PyramidalImageType +{ + bim_UINT8_PYRAMIDAL_IMG, /* byte representation of pyramical image */ + bim_UINT16_PYRAMIDAL_IMG /* 16-bit representation of pyramical image */ +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** Warps an image with intermediate pyramidal downscaling if possible in order to minimize aliasing + * The actual warping happens using pixel interpolation + * *bufPtrA is an intermediate byte array that holds downscaled data (only needed when pyramidal downscaling happens; can be NULL otherwise) + * scaleThresholdA (16.16): + * specifies the minimum scale ratio (inImage/outImage) required to initiate prior filtering + * A value range of 2.0...4.0 is recommended (<= 0.0: disabled) + * + * offsPtrA specifies the pixel position (0,0) in the input image (format 16.0) + */ +void bim_filterWarpInterpolation( struct bbs_Context* cpA, + uint8* dstImagePtrA, + const uint8* srcImagePtrA, + uint32 srcImageWidthA, + uint32 srcImageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_Flt16Alt2D* altPtrA, + uint32 dstWidthA, + uint32 dstHeightA, + struct bbs_UInt8Arr* bufPtrA, + uint32 scaleThresholdA ); + +/** Warps an image with intermediate pyramidal downscaling if possible in order to minimize aliasing + * The actual warping happens using pixel replication (fast but prone to artefacts) + * *bufPtrA is an intermediate byte array that holds downscaled data (only needed when pyramidal downscaling happens; can be NULL otherwise) + * scaleThresholdA (16.16): + * specifies the minimum scale ratio (inImage/outImage) required to initiate prior filtering + * A value range of 2.0...4.0 is recommended (0.0: disabled) + * offsPtrA specifies the pixel position (0,0) in the input image (format 16.0) + */ +void bim_filterWarpPixelReplication( struct bbs_Context* cpA, + uint8* dstImagePtrA, + const uint8* srcImagePtrA, + uint32 srcImageWidthA, + uint32 srcImageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_Flt16Alt2D* altPtrA, + uint32 dstWidthA, + uint32 dstHeightA, + struct bbs_UInt8Arr* bufPtrA, + uint32 scaleThresholdA ); + +/** Selects proper warp function above + * offsPtrA specifies the pixel position (0,0) in the input image (format 16.0) + */ +void bim_filterWarp( struct bbs_Context* cpA, + uint8* dstImagePtrA, + const uint8* srcImagePtrA, + uint32 srcImageWidthA, + uint32 srcImageHeightA, + const struct bts_Int16Vec2D* offsPtrA, + const struct bts_Flt16Alt2D* altPtrA, + uint32 dstWidthA, + uint32 dstHeightA, + struct bbs_UInt8Arr* bufPtrA, + uint32 scaleThresholdA, + flag interpolateA ); + +#endif /* bim_FUNCTIONS_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/HistoEq.c b/Embedded/common/src/b_ImageEm/HistoEq.c new file mode 100644 index 0000000..0b73b21 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/HistoEq.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/Math.h" +#include "b_ImageEm/HistoEq.h" +#include "b_ImageEm/UInt8Image.h" + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/** Computes grey level histogram of given image. */ +void bim_createHisto( struct bbs_Context* cpA, + uint16* histoPtrA, + const struct bim_UInt8Image* imagePtrA ) +{ + uint32 iL; + uint16* dstPtrL; + const uint8* srcPtrL; + + /* init histogram array with 0 */ + dstPtrL = histoPtrA; + for( iL = 256; iL > 0; iL-- ) + { + *dstPtrL++ = 0; + } + + /* calculate histogram */ + srcPtrL = imagePtrA->arrE.arrPtrE; + dstPtrL = histoPtrA; + for( iL = imagePtrA->arrE.sizeE; iL > 0; iL-- ) + { + dstPtrL[ *srcPtrL++ ]++; + } +} + +/* ------------------------------------------------------------------------- */ + +/** Computes grey level histogram of given image. */ +void bim_createHistoOfSection( struct bbs_Context* cpA, + uint16* histoPtrA, + const struct bts_Int16Rect* sectionPtrA, + const struct bim_UInt8Image* imagePtrA ) +{ + uint32 xL, yL; + const uint8* srcPtrL; + uint16* dstPtrL; + struct bts_Int16Rect sectionL = *sectionPtrA; + uint32 sectWidthL; + uint32 sectHeightL; + int32 imgWidthL = imagePtrA->widthE; + int32 imgHeightL = imagePtrA->heightE; + + /* adjustments */ + sectionL.x1E = bbs_max( 0, sectionL.x1E ); + sectionL.x1E = bbs_min( imgWidthL, sectionL.x1E ); + sectionL.x2E = bbs_max( 0, sectionL.x2E ); + sectionL.x2E = bbs_min( imgWidthL, sectionL.x2E ); + sectionL.y1E = bbs_max( 0, sectionL.y1E ); + sectionL.y1E = bbs_min( imgHeightL, sectionL.y1E ); + sectionL.y2E = bbs_max( 0, sectionL.y2E ); + sectionL.y2E = bbs_min( imgHeightL, sectionL.y2E ); + + sectWidthL = sectionL.x2E - sectionL.x1E; + sectHeightL = sectionL.y2E - sectionL.y1E; + + /* init histogram with 0 */ + dstPtrL = histoPtrA; + for( xL = 256; xL > 0; xL-- ) + { + *dstPtrL++ = 0; + } + + /* calculate histogram */ + srcPtrL = imagePtrA->arrE.arrPtrE + sectionL.y1E * imgWidthL + sectionL.x1E; + dstPtrL = histoPtrA; + for( yL = 0; yL < sectHeightL; yL++ ) + { + for( xL = 0; xL < sectWidthL; xL++ ) + { + dstPtrL[ *srcPtrL++ ]++; + } + srcPtrL += imgWidthL - sectWidthL; + } +} + +/* ------------------------------------------------------------------------- */ + +/** equalize image using given histogram */ +void bim_equalize( struct bbs_Context* cpA, + struct bim_UInt8Image* imagePtrA, + const uint16* histoPtrA ) +{ + uint32 kL; + uint32 sumL = 0; + uint32 totalSumL = 0; + const uint16* histoArrPtrL; + uint8* dstPtrL; + uint8 mappingL[ 256 ]; + + /* determine number of counts in histogram */ + histoArrPtrL = histoPtrA; + for( kL = 256; kL > 0; kL-- ) + { + totalSumL += *histoArrPtrL++; + } + + if( totalSumL == 0 ) totalSumL = 1; + + /* compute transfer function (cumulative histogram) */ + histoArrPtrL = histoPtrA; + for( kL = 0; kL < 256; kL++ ) + { + sumL += *histoArrPtrL++; + mappingL[ kL ] = ( sumL * 255 ) / totalSumL; + } + + /* remap pixel values */ + dstPtrL = imagePtrA->arrE.arrPtrE; + for( kL = imagePtrA->arrE.sizeE; kL > 0; kL-- ) + { + *dstPtrL = mappingL[ *dstPtrL ]; + dstPtrL++; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_equalize( struct bbs_Context* cpA, + struct bim_UInt8Image* imagePtrA ) +{ + uint16 histogramL[ 256 ]; + bim_createHisto( cpA, histogramL, imagePtrA ); + bim_equalize( cpA, imagePtrA, histogramL ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_equalizeSection( struct bbs_Context* cpA, + struct bim_UInt8Image* imagePtrA, + const struct bts_Int16Rect* sectionPtrA ) +{ + uint16 histogramL[ 256 ]; + bim_createHistoOfSection( cpA, histogramL, sectionPtrA, imagePtrA ); + bim_equalize( cpA, imagePtrA, histogramL ); +} + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_ImageEm/HistoEq.h b/Embedded/common/src/b_ImageEm/HistoEq.h new file mode 100644 index 0000000..82f2286 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/HistoEq.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_HISTOEQ_EM_H +#define bim_HISTOEQ_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_ImageEm/UInt8Image.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bim_UInt8Image; +struct bts_Int16Rect; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** Histogram equalization of image */ +void bim_UInt8Image_equalize( struct bbs_Context* cpA, + struct bim_UInt8Image* imagePtrA ); + +/** Histogram equalization using histogram generated from subregion. + * While the histogram is taken only in the specified sub-section of the + * image, the equalization, i.e. remapping of the pixel values, is + * performed on the whole image. + * + * @param imagePtrA pointer to image to be equalized + * @param sectionPtrA section specifying region in image where histogram is + * generated from + */ +void bim_UInt8Image_equalizeSection( struct bbs_Context* cpA, + struct bim_UInt8Image* imagePtrA, + const struct bts_Int16Rect* sectionPtrA ); + +/* ------------------------------------------------------------------------- */ + +#endif /* bim_HISTOEQ_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/HistoEq16.c b/Embedded/common/src/b_ImageEm/HistoEq16.c new file mode 100644 index 0000000..f45c1e3 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/HistoEq16.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_BasicEm/Math.h" +#include "b_ImageEm/HistoEq16.h" +#include "b_ImageEm/UInt16ByteImage.h" + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/** Computes grey level histogram of given image. */ +void bim_createHisto16( uint16* histoPtrA, + const struct bim_UInt16ByteImage* imagePtrA ) +{ + uint32 iL; + uint16* dstPtrL; + const uint16* srcPtrL; + + /* init histogram array with 0 */ + dstPtrL = histoPtrA; + for( iL = 256; iL > 0; iL-- ) + { + *dstPtrL++ = 0; + } + + srcPtrL = imagePtrA->arrE.arrPtrE; + dstPtrL = histoPtrA; + /* calculate histogram (assuming even image width) */ + for( iL = imagePtrA->arrE.sizeE; iL > 0; iL-- ) + { + dstPtrL[ ( *srcPtrL & 0x0FF ) ]++; + dstPtrL[ ( *srcPtrL >> 8 ) ]++; + srcPtrL++; + } +} + +/* ------------------------------------------------------------------------- */ + +/** Computes grey level histogram of given image. */ +void bim_createHistoOfSection16( uint16* histoPtrA, + const struct bts_Int16Rect* sectionPtrA, + const struct bim_UInt16ByteImage* imagePtrA ) +{ + uint32 xL, yL; + const uint16* srcPtrL; + uint16* dstPtrL; + struct bts_Int16Rect sectionL = *sectionPtrA; + uint32 sectWidthL; + uint32 sectHeightL; + int32 imgWidthL = imagePtrA->widthE; + int32 imgHeightL = imagePtrA->heightE; + + bbs_ERROR0( "bim_createHistoOfSection16(...): not implemented" ); + + /* adjustments */ + sectionL.x1E = bbs_max( 0, sectionL.x1E ); + sectionL.x1E = bbs_min( imgWidthL, sectionL.x1E ); + sectionL.x2E = bbs_max( 0, sectionL.x2E ); + sectionL.x2E = bbs_min( imgWidthL, sectionL.x2E ); + sectionL.y1E = bbs_max( 0, sectionL.y1E ); + sectionL.y1E = bbs_min( imgHeightL, sectionL.y1E ); + sectionL.y2E = bbs_max( 0, sectionL.y2E ); + sectionL.y2E = bbs_min( imgHeightL, sectionL.y2E ); + + sectWidthL = sectionL.x2E - sectionL.x1E; + sectHeightL = sectionL.y2E - sectionL.y1E; + + /* init histogram with 0 */ + dstPtrL = histoPtrA; + for( xL = 256; xL > 0; xL-- ) + { + *dstPtrL++ = 0; + } + + /* calculate histogram */ + srcPtrL = imagePtrA->arrE.arrPtrE + sectionL.y1E * imgWidthL + sectionL.x1E; + dstPtrL = histoPtrA; + for( yL = 0; yL < sectHeightL; yL++ ) + { + for( xL = 0; xL < sectWidthL; xL++ ) + { + dstPtrL[ ( *srcPtrL & 0x0FF ) ]++; + dstPtrL[ ( *srcPtrL >> 8 ) ]++; + srcPtrL++; + /* dstPtrL[ *srcPtrL++ ]++; */ + } + srcPtrL += imgWidthL - sectWidthL; + } +} + +/* ------------------------------------------------------------------------- */ + +/** equalize image using given histogram */ +void bim_equalize16( struct bim_UInt16ByteImage* imagePtrA, + const uint16* histoPtrA ) +{ + uint32 kL; + uint32 sumL = 0; + uint32 totalSumL = 0; + const uint16* histoArrPtrL; + uint16* dstPtrL; + uint16 mappingL[ 256 ]; + + /* determine number of counts in histogram */ + histoArrPtrL = histoPtrA; + for( kL = 256; kL > 0; kL-- ) + { + totalSumL += *histoArrPtrL++; + } + + if( totalSumL == 0 ) totalSumL = 1; + + /* compute transfer function (cumulative histogram) */ + histoArrPtrL = histoPtrA; + for( kL = 0; kL < 256; kL++ ) + { + sumL += *histoArrPtrL++; + mappingL[ kL ] = ( sumL * 255 ) / totalSumL; + } + + /* remap pixel values */ + dstPtrL = imagePtrA->arrE.arrPtrE; + for( kL = imagePtrA->arrE.sizeE; kL > 0; kL-- ) + { + *dstPtrL = mappingL[ *dstPtrL & 0x00FF ] | ( mappingL[ *dstPtrL >> 8 ] << 8 ); + dstPtrL++; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_equalize( struct bim_UInt16ByteImage* imagePtrA ) +{ + uint16 histogramL[ 256 ]; + bim_createHisto16( histogramL, imagePtrA ); + bim_equalize16( imagePtrA, histogramL ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_equalizeSection( struct bim_UInt16ByteImage* imagePtrA, + const struct bts_Int16Rect* sectionPtrA ) +{ + uint16 histogramL[ 256 ]; + bim_createHistoOfSection16( histogramL, sectionPtrA, imagePtrA ); + bim_equalize16( imagePtrA, histogramL ); +} + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_ImageEm/HistoEq16.h b/Embedded/common/src/b_ImageEm/HistoEq16.h new file mode 100644 index 0000000..94907fa --- /dev/null +++ b/Embedded/common/src/b_ImageEm/HistoEq16.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_HISTOEQ16_EM_H +#define bim_HISTOEQ16_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +/* ---- related objects --------------------------------------------------- */ + +struct bim_UInt16ByteImage; +struct bts_Int16Rect; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** Histogram equalization of image */ +void bim_UInt16ByteImage_equalize( struct bim_UInt16ByteImage* imagePtrA ); + +/** Histogram equalization using histogram generated from subregion. + * While the histogram is taken only in the specified sub-section of the + * image, the equalization, i.e. remapping of the pixel values, is + * performed on the whole image. + * + * @param imagePtrA pointer to image to be equalized + * @param sectionPtrA section specifying region in image where histogram is + * generated from + */ +void bim_UInt16ByteImage_equalizeSection( struct bim_UInt16ByteImage* imagePtrA, + const struct bts_Int16Rect* sectionPtrA ); + +/* ------------------------------------------------------------------------- */ + +#endif /* bim_HISTOEQ16_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/ToneDownBGSupp.c b/Embedded/common/src/b_ImageEm/ToneDownBGSupp.c new file mode 100644 index 0000000..70c7aff --- /dev/null +++ b/Embedded/common/src/b_ImageEm/ToneDownBGSupp.c @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEM/Math.h" +#include "b_BasicEM/Memory.h" +#include "b_BasicEM/Int16Arr.h" +#include "b_BasicEM/Int32Arr.h" + +#include "b_ImageEM/ToneDownBGSupp.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_ToneDownBGSupp_BGGreyLevelOutside( struct bim_UInt8Image* imgA, + struct bts_Int16Rect* rectA, + int16 rectExpansionA, + uint32* meanBGGrayLevelA ) +{ + /* image access */ + int16 iL, jL; + uint8 *imgPtrL = 0; + uint8 *imgPtrMaxL = 0; + + /* the sum is possibly a large number. e.g. for a 512x512 byte image, maximum brightness, sumL is 7x10E7 */ + uint32 sumL, ctrL; + + /* the rectangle vertices */ + int16 rectXMinL, rectXMaxL, rectYMinL, rectYMaxL; + int16 rectIxXMinL, rectIxXMaxL, rectIxYMinL, rectIxYMaxL; + + /* expand the rectangle */ + + /* expand rectangle. the result is called the ROI */ + rectXMinL = rectA->x1E + rectExpansionA; + rectXMaxL = rectA->x2E - rectExpansionA; + rectYMinL = rectA->y1E + rectExpansionA; + rectYMaxL = rectA->y2E - rectExpansionA; + + rectIxXMinL = bbs_max( rectXMinL, ( int16 ) 0 ); + rectIxXMaxL = bbs_max( rectXMaxL, ( int16 ) 0 ); + rectIxXMaxL = bbs_min( rectXMaxL, ( int16 ) imgA->widthE ); + rectIxYMinL = bbs_max( rectYMinL, ( int16 ) 0 ); + rectIxYMaxL = bbs_min( rectYMaxL, ( int16 ) 0 ); + rectIxYMaxL = bbs_min( rectYMaxL, ( int16 ) imgA->heightE ); + + /* avoid negative overlap */ + rectIxXMinL = bbs_min( rectIxXMinL, rectIxXMaxL ); + rectIxYMinL = bbs_min( rectIxYMinL, rectIxYMaxL ); + +/* printf( "new xmin=%d, xmax=%d, ymin=%d,ymax=%d \n", rectIxXMinL, rectIxXMaxL, rectIxYMinL, rectIxYMaxL ); */ + + /* part 1: sum up all the lines above the ROI */ + + sumL = 0; + ctrL = 0; + + imgPtrL = &(imgA->arrE.arrPtrE[ 0 ]); + ctrL += rectIxYMinL * imgA->widthE; + imgPtrMaxL = imgPtrL + rectIxYMinL * imgA->widthE; + while ( imgPtrL < imgPtrMaxL ) + { + sumL += *imgPtrL; + imgPtrL++; + } + + /* part 2: sum up all the lines below the ROI */ + + ctrL += ( imgA->heightE - rectIxYMaxL ) * imgA->widthE; + + imgPtrL = &(imgA->arrE.arrPtrE[ rectIxYMaxL * imgA->widthE ]); + imgPtrMaxL = &(imgA->arrE.arrPtrE[ imgA->heightE * imgA->widthE ]); + while ( imgPtrL < imgPtrMaxL ) + { + sumL += *imgPtrL; + imgPtrL++; + } + + /* part 3: sum over the two vertically adjacent blocks */ + + for ( jL = rectIxYMinL; jL < rectIxYMaxL; jL++ ) + { + imgPtrL = &(imgA->arrE.arrPtrE[ rectIxYMinL * imgA->widthE ]); + ctrL += bbs_max( 0, rectIxXMinL ); + + for ( iL = 0; iL < rectIxXMinL; iL++ ) + { + sumL += imgPtrL[ iL ]; + } + + if( ( int32 )imgA->widthE > ( int32 )rectIxXMaxL ) + { + ctrL += ( int32 )imgA->widthE - ( int32 )rectIxXMaxL; + } + + for ( iL = rectIxXMaxL; iL < ( int16 ) imgA->widthE; iL++ ) + { + sumL += imgPtrL[ iL ]; + } + } + + /* printf( "new sum = %d, new ctr = %d \n", sumL, ctrL ); */ + + /* result is bpb=[16.16] */ + *meanBGGrayLevelA = ( sumL << 16 ) / ( uint32 ) ctrL; + + /* result is bpb=[16.16] */ + *meanBGGrayLevelA = sumL / ctrL; /* integer division */ + sumL = sumL - *meanBGGrayLevelA * ctrL; /* result always greater than or equal to zero */ + *meanBGGrayLevelA = *meanBGGrayLevelA << 16; /* shift to left */ + *meanBGGrayLevelA = *meanBGGrayLevelA + ( sumL << 16 ) / ctrL; /* add residue */ + +} + +/* ------------------------------------------------------------------------- */ + +void bim_ToneDownBGSupp_BGGreyLevelContour( struct bim_UInt8Image* imgA, + struct bts_Int16Rect* rectA, + uint32* meanBGGrayLevelA ) +{ + /* image access */ + int16 iL; + uint8 *imgPtr0L = 0; + uint8 *imgPtr1L = 0; + + /* the sum is possibly a large number. e.g. for a 512x512 byte image, maximum brightness, sumL is 7x10E7 */ + uint32 sumL, ctrL; + + /* the rectangle vertices */ + int16 rectXMinL, rectXMaxL, rectYMinL, rectYMaxL; + int16 rectIxXMinL, rectIxXMaxL, rectIxYMinL, rectIxYMaxL; + int16 rectMinWidthL = 10, rectMinHeightL = 10; + int16 rectXMidPointL, rectYMidPointL; + int16 shiftXRectL, shiftYRectL; + + /* cut off the rectangle at the image bounaries + * when its size becomes too small + * the rectangle is shifted back inside the image */ + + /* cut off at image boundaries */ + rectXMinL = rectA->x1E; + rectXMaxL = rectA->x2E; + rectYMinL = rectA->y1E; + rectYMaxL = rectA->y2E; + + rectIxXMinL = bbs_max( rectXMinL, ( int16 ) 0 ); + rectIxXMaxL = bbs_max( rectXMaxL, ( int16 ) 0 ); + rectIxXMaxL = bbs_min( rectXMaxL, ( int16 ) imgA->widthE ); + rectIxYMinL = bbs_max( rectYMinL, ( int16 ) 0 ); + rectIxYMaxL = bbs_min( rectYMaxL, ( int16 ) 0 ); + rectIxYMaxL = bbs_min( rectYMaxL, ( int16 ) imgA->heightE ); + + /* shift back into image */ + shiftXRectL = 0; + shiftYRectL = 0; + if ( rectIxXMaxL - rectIxXMinL < rectMinWidthL ) + { + rectXMidPointL = ( rectIxXMaxL + rectIxXMinL ) >> 1; + rectIxXMinL = rectXMidPointL - ( rectMinWidthL >> 1 ); + rectIxXMaxL = rectXMidPointL + ( rectMinWidthL >> 1 ); + + if ( rectIxXMinL < 0 ) + { + shiftXRectL = -rectIxXMinL; + } + if ( rectIxXMaxL > ( int16 ) imgA->widthE ) + { + shiftXRectL = rectIxXMaxL - ( int16 ) imgA->widthE; + } + } + if ( rectIxYMaxL - rectIxYMinL < rectMinHeightL ) + { + rectYMidPointL = ( rectIxYMaxL + rectIxYMinL ) >> 1; + rectIxYMinL = rectYMidPointL - ( rectMinWidthL >> 1 ); + rectIxYMaxL = rectYMidPointL + ( rectMinWidthL >> 1 ); + + if ( rectIxYMinL < 0 ) + { + shiftXRectL = -rectIxYMinL; + } + if ( rectIxYMaxL > ( int16 ) imgA->widthE ) + { + shiftXRectL = rectIxYMaxL - ( int16 ) imgA->widthE; + } + } + rectIxXMinL += shiftXRectL; + rectIxXMaxL += shiftXRectL; + rectIxYMinL += shiftYRectL; + rectIxYMaxL += shiftYRectL; + + /* when the image is small, there is a possibility that the shifted rectangle lies outside of the image. + * => lop off the rectangle at image boundaries once again */ + rectIxXMinL = bbs_max( rectXMinL, ( int16 ) 0 ); + rectIxXMaxL = bbs_min( rectXMaxL, ( int16 ) imgA->widthE ); + rectIxYMinL = bbs_max( rectYMinL, ( int16 ) 0 ); + rectIxYMaxL = bbs_min( rectYMaxL, ( int16 ) imgA->heightE ); + + + sumL = 0; + ctrL = 0; + ctrL += ( rectIxXMaxL - rectIxXMinL ) << 1; + ctrL += ( rectIxYMaxL - rectIxYMinL - 2 ) << 1; + + /* loop over the contour */ + imgPtr0L = &(imgA->arrE.arrPtrE[ rectIxYMinL * imgA->widthE ]); + imgPtr1L = &(imgA->arrE.arrPtrE[ ( rectIxYMaxL - 1 ) * imgA->widthE ]); + for ( iL = rectIxXMinL; iL < rectIxXMaxL; iL++ ) + { + sumL += imgPtr0L[ iL ]; + sumL += imgPtr1L[ iL ]; + } + imgPtr0L = &(imgA->arrE.arrPtrE[ ( rectIxYMinL + 1 ) * imgA->widthE + rectIxXMinL ]); + imgPtr1L = &(imgA->arrE.arrPtrE[ ( rectIxYMinL + 1 ) * imgA->widthE + rectIxXMaxL - 1 ]); + for ( iL = rectIxYMinL + 1; iL < rectIxYMaxL - 1; iL++ ) + { + sumL += *imgPtr0L; + sumL += *imgPtr1L; + imgPtr0L += imgA->widthE; + imgPtr1L += imgA->widthE; + } + + + /* printf( "new sum = %d, new ctr = %d \n", sumL, ctrL ); */ + + /* result is bpb=[16.16] */ + *meanBGGrayLevelA = ( sumL << 16 ) / ( uint32 ) ctrL; + + /* result is bpb=[16.16] */ + *meanBGGrayLevelA = sumL / ctrL; /* integer division */ + sumL = sumL - *meanBGGrayLevelA * ctrL; /* result always greater than or equal to zero */ + *meanBGGrayLevelA = *meanBGGrayLevelA << 16; /* shift to left */ + *meanBGGrayLevelA = *meanBGGrayLevelA + ( sumL << 16 ) / ctrL; /* add residue */ +} + +/* ------------------------------------------------------------------------- */ + +void bim_ToneDownBGSupp_suppress( struct bim_UInt8Image* imgA, + struct bts_Int16Rect* rectA, + int16 rectShrinkageA, + int32 toneDownFactorA, /* ToDo: change to int16, bpb=[0.16] */ + int32 cutOffAccuracyA ) +{ + /* ((( variable declarations begin ))) */ + + /* the rectangle vertices */ + int16 rectXMinL, rectXMaxL, rectYMinL, rectYMaxL; + int16 rectIxXMinL, rectIxXMaxL, rectIxYMinL, rectIxYMaxL; + int16 rectShrinkageL; + + /* the BG mean grey value */ + uint8 meanBGGreyBBPL; + uint32 meanBGGreyLevelL; + uint32 meanBGGreyLevelByteL; + int32 meanBGGreyLevelLongL; + + /* maximum reach of the ROI */ + uint32 maxROIReachL; + int16 rOIReachXMinL, rOIReachXMaxL, rOIReachYMinL, rOIReachYMaxL; + int16 rOIReachIxXMinL, rOIReachIxXMaxL, rOIReachIxYMinL, rOIReachIxYMaxL; + int16 ridgeIxLeftL, ridgeIxRightL; + + /* tone down table */ + struct bbs_Int32Arr toneDownFactorsL; /* ToDo: change int32 bpb=[16.16] to uint bpb=[0.16] */ + int32 toneDownFactorPowA; + int32* toneDownFactorsPtrL; + int32 ctrL; + + /* image access */ + int16 iL, jL; + uint8 *imgPtrL = 0; /* welcome back to the stoneage */ + + /* weighting formula */ + int32 weightL, invWeightL; /* R=[0.0...1.0], bpb=[16.16] */ + int32 opSrcL, opBGL, sumL; /* R=[0.0...255.0], bpb=[24,8] */ + + /* ((( variable declarations end ))) */ + + /* make sure that the width is smaller than the rectangle */ + rectShrinkageL = rectShrinkageA; + rectShrinkageL = bbs_min( rectShrinkageL, ( rectA->x2E - rectA->x1E ) >> 1 ); + rectShrinkageL = bbs_min( rectShrinkageL, ( rectA->y2E - rectA->y1E ) >> 1 ); + + /* shrink rectangle. the result is called the ROI */ + rectXMinL = rectA->x1E + rectShrinkageL; + rectXMaxL = rectA->x2E - rectShrinkageL; + rectYMinL = rectA->y1E + rectShrinkageL; + rectYMaxL = rectA->y2E - rectShrinkageL; + + rectIxXMinL = bbs_max( rectXMinL, 0 ); + rectIxXMinL = bbs_min( rectIxXMinL, ( int16 ) imgA->widthE ); + rectIxXMaxL = bbs_min( rectXMaxL, ( int16 ) imgA->widthE ); + rectIxXMaxL = bbs_max( rectIxXMaxL, 0 ); + + rectIxYMinL = bbs_max( rectYMinL, 0 ); + rectIxYMinL = bbs_min( rectIxYMinL, ( int16 ) imgA->heightE ); + rectIxYMaxL = bbs_min( rectYMaxL, ( int16 ) imgA->heightE ); + rectIxYMaxL = bbs_max( rectIxYMaxL, 0 ); + + /* exit function at exceptional cases */ + if ( ( imgA->heightE == 0 ) || ( imgA->widthE == 0 ) ) return; + if ( rectShrinkageL == 0 ) return; + + /* compute the mean gray level aloong the rectangle contour */ + bim_ToneDownBGSupp_BGGreyLevelContour( imgA, rectA, &meanBGGreyLevelL ); + + /* printf( "new mean BG gray value = %f \n", ( float ) meanBGGreyLevelL / 65536.0f ); */ + + /* R=[0.0...255.0], bpb=[24.8] */ + meanBGGreyBBPL = 16; + meanBGGreyLevelL = ( 128 << meanBGGreyBBPL ); + meanBGGreyLevelByteL = meanBGGreyLevelL >> meanBGGreyBBPL; + meanBGGreyLevelLongL = ( 128 << meanBGGreyBBPL ); + /* ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo ToDo */ + + /* this function computes an image that moving away from the ROI gradually fades to + * the background grey level BG according to the formula + * tonedImg = w srcImg + (1-w) BG + * w depends on the distance to the ROI. + * there is a distance maxROIReachL beyond which + * the importance of the source image + * relative to the BG in the equation + * falls below a small threshold. + * in those regions the toned image is equal to + * the mean BG grey value. i.e. w=0, tonedImg = BG */ + maxROIReachL = bbs_max( imgA->widthE, imgA->heightE ); + + /* pre-compute an array of tone down factors. R=[0.0...1.0] => bpb=[0.16] (idealy, bpb=[16.16] due to missing uInt16Arr ) */ + bbs_Int32Arr_init( &toneDownFactorsL ); + bbs_Int32Arr_size( &toneDownFactorsL, maxROIReachL ); + toneDownFactorPowA = toneDownFactorA; + toneDownFactorsPtrL = toneDownFactorsL.arrPtrE; + for( ctrL = 0; ctrL < ( int32 ) maxROIReachL && toneDownFactorPowA > cutOffAccuracyA; ctrL++ ) + { + toneDownFactorsPtrL[ ctrL ] = toneDownFactorPowA; + toneDownFactorPowA = toneDownFactorPowA * ( toneDownFactorA >> 1 ); + toneDownFactorPowA = toneDownFactorPowA >> 15; + + /* make active to check the error that accumulates by recursively multiplying factors */ + /* printf( "pow = %d, tonedown dec = %d, tonedown float = %f \n", ctrL + 2, toneDownFactorPowA, toneDownFactorPowA / 65536.0f ); */ + } + maxROIReachL = ctrL; + /* printf( "maxROIReachL = %d, tonedown = %d \n", maxROIReachL, toneDownFactorPowA ); */ + + /* move across the image one row at a time. + * (1) fill the outside frame with BG grey level + * (2) blend in the original image moving towards the ROI + */ + + rOIReachXMinL = rectXMinL - ( int32 ) maxROIReachL; + rOIReachXMaxL = rectXMaxL + ( int32 ) maxROIReachL; + rOIReachYMinL = rectYMinL - ( int32 ) maxROIReachL; + rOIReachYMaxL = rectYMaxL + ( int32 ) maxROIReachL; + + rOIReachIxXMinL = bbs_max( rOIReachXMinL, ( int16 ) 0 ); + rOIReachIxXMinL = bbs_min( rOIReachIxXMinL, ( int16 ) imgA->widthE ); + rOIReachIxXMaxL = bbs_min( rOIReachXMaxL, ( int16 ) imgA->widthE ); + rOIReachIxXMaxL = bbs_max( rOIReachIxXMaxL, ( int16 ) 0 ); + + rOIReachIxYMinL = bbs_max( rOIReachYMinL, ( int16 ) 0 ); + rOIReachIxYMinL = bbs_min( rOIReachIxYMinL, ( int16 ) imgA->heightE ); + rOIReachIxYMaxL = bbs_min( rOIReachYMaxL, ( int16 ) imgA->heightE ); + rOIReachIxYMaxL = bbs_max( rOIReachIxYMaxL, ( int16 ) 0 ); + + /* (1) far from the ROI the image is filled with the BG grey value */ + + imgPtrL = 0; + for ( jL = 0; jL < rOIReachYMinL; jL++ ) + { + imgPtrL = &( imgA->arrE.arrPtrE[ jL * imgA->widthE ] ); + for ( iL = 0; iL <= ( int16 ) imgA->widthE; iL++ ) + { + imgPtrL[ iL ] = meanBGGreyLevelByteL; + } + } + for ( jL = rOIReachYMaxL; jL < ( int16 ) imgA->heightE; jL++ ) + { + imgPtrL = &( imgA->arrE.arrPtrE[ jL * imgA->widthE ] ); + for ( iL = 0; iL <= ( int16 ) imgA->widthE; iL++ ) + { + imgPtrL[ iL ] = meanBGGreyLevelByteL; + } + } + for ( jL = rOIReachIxYMinL; jL < rOIReachIxYMaxL; jL++ ) + { + imgPtrL = &( imgA->arrE.arrPtrE[ jL * imgA->widthE ] ); + for ( iL = 0; iL < rOIReachXMinL; iL++ ) + { + imgPtrL[ iL ] = meanBGGreyLevelByteL; + } + for ( iL = rOIReachXMaxL; iL < ( int16 ) imgA->widthE; iL++ ) + { + imgPtrL[ iL ] = meanBGGreyLevelByteL; + } + } + + /* (2) blend from ROI to outside regions */ + + for ( jL = rOIReachIxYMinL; jL < rectIxYMinL; jL++ ) + { + /* the factor for one row is a constant */ + weightL = ( int32 ) toneDownFactorsPtrL[ maxROIReachL - 1 - ( jL - rOIReachYMinL ) ]; + invWeightL = 0x00010000 - weightL; + opBGL = ( meanBGGreyLevelLongL >> 9 ) * invWeightL; /* result is bpb=[8,24] */ + opBGL = opBGL >> 7; + imgPtrL = &( imgA->arrE.arrPtrE[ jL * imgA->widthE ] ); + + /* compute the ridge position */ + ridgeIxLeftL = bbs_max( 0, rOIReachXMinL + jL - rOIReachYMinL ); + ridgeIxRightL = bbs_min( ( int16 ) imgA->widthE - 1, rOIReachXMaxL - 1 - ( jL - rOIReachYMinL ) ); + + /* loop over all elements from left ridge through right ridge */ + for ( iL = ridgeIxLeftL; iL <= ridgeIxRightL; iL++ ) + { + opSrcL = imgPtrL[ iL ]; /* leave at byte */ + opSrcL = opSrcL * weightL; /* result is bpb=[16,16] */ + sumL = opSrcL + opBGL; /* OF impossible */ + imgPtrL[ iL ] = sumL >> 16; /* round to byte */ + } + } + for ( jL = rOIReachIxYMaxL - 1; jL >= rectIxYMaxL; jL-- ) + { + /* the factor for one row is a constant */ + weightL = ( int32 ) toneDownFactorsPtrL[ maxROIReachL - 1 - ( rOIReachYMaxL - 1 - jL ) ]; + invWeightL = 0x00010000 - weightL; + opBGL = ( meanBGGreyLevelLongL >> 9 ) * invWeightL; /* result is bpb=[8,24] */ + opBGL = opBGL >> 7; + imgPtrL = &( imgA->arrE.arrPtrE[ jL * imgA->widthE ] ); + + /* compute the ridge position */ + ridgeIxLeftL = bbs_max( 0, rOIReachXMinL + ( rOIReachYMaxL - 1 - jL ) ); + ridgeIxRightL = bbs_min( ( int16 ) imgA->widthE - 1, rOIReachXMaxL - 1 - ( rOIReachYMaxL - 1 - jL ) ); + + /* loop over all elements from left ridge through right ridge */ + for ( iL = ridgeIxLeftL; iL <= ridgeIxRightL; iL++ ) + { + opSrcL = imgPtrL[ iL ]; /* leave at byte */ + opSrcL = opSrcL * weightL; /* result is bpb=[16,16] */ + sumL = opSrcL + opBGL; /* OF impossible */ + imgPtrL[ iL ] = sumL >> 16; /* round to byte */ + } + } + for ( jL = rOIReachIxYMinL; jL < rOIReachIxYMaxL; jL++ ) + { + imgPtrL = &( imgA->arrE.arrPtrE[ jL * imgA->widthE ] ); + + ridgeIxLeftL = bbs_min( rOIReachXMinL + ( jL - rOIReachYMinL ) - 1, rectXMinL - 1 ); + ridgeIxLeftL = bbs_min( ridgeIxLeftL, rOIReachXMinL + ( rOIReachYMaxL - 1 - jL ) - 1 ); + for ( iL = rOIReachIxXMinL; iL <= ridgeIxLeftL; iL++ ) + { + weightL = ( int32 ) toneDownFactorsPtrL[ maxROIReachL - 1 - ( iL - rOIReachXMinL ) ]; + invWeightL = 0x00010000 - weightL; + opBGL = ( meanBGGreyLevelLongL >> 9 ) * invWeightL; /* result is bpb=[16,16] */ + opBGL = opBGL >> 7; + + opSrcL = imgPtrL[ iL ]; /* leave at byte */ + opSrcL = opSrcL * weightL; /* result is bpb=[16,16] */ + sumL = opSrcL + opBGL; /* OF impossible */ + imgPtrL[ iL ] = sumL >> 16; /* round to byte */ + } + + ridgeIxRightL = bbs_max( rOIReachXMaxL - 1 - ( jL - rOIReachYMinL ) + 1 , rectXMaxL ); + ridgeIxRightL = bbs_max( ridgeIxRightL, rOIReachXMaxL - 1 - ( rOIReachYMaxL - 1 - jL ) + 1 ); + for ( iL = ridgeIxRightL; iL < rOIReachIxXMaxL; iL++ ) + { + weightL = ( int32 ) toneDownFactorsPtrL[ iL - rectXMaxL ]; + invWeightL = 0x00010000 - weightL; + opBGL = ( meanBGGreyLevelLongL >> 9 ) * invWeightL; /* result is bpb=[16,16] */ + opBGL = opBGL >> 7; + + opSrcL = imgPtrL[ iL ]; /* leave at byte */ + opSrcL = opSrcL * weightL; /* result is bpb=[16,16] */ + sumL = opSrcL + opBGL; /* OF impossible */ + imgPtrL[ iL ] = sumL >> 16; /* round to byte */ + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/Embedded/common/src/b_ImageEm/ToneDownBGSupp.h b/Embedded/common/src/b_ImageEm/ToneDownBGSupp.h new file mode 100644 index 0000000..8ac76be --- /dev/null +++ b/Embedded/common/src/b_ImageEm/ToneDownBGSupp.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_TONE_DOWN_BG_SUPP_EM_H +#define bim_TONE_DOWN_BG_SUPP_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_ImageEm/UInt8Image.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes the mean BG gray level outside of the rectangle */ +void bim_ToneDownBGSupp_BGGreyLevelOutside( struct bim_UInt8Image* imgA, + struct bts_Int16Rect* rectA, + int16 rectExpansionA, /* this is a remnant of the original c++ class */ + uint32* meanBGGrayLevelA ); /* was mistakenly converted to c */ + +/** computes the mean BG gray level right on the rectangle contours */ +void bim_ToneDownBGSupp_BGGreyLevelContour( struct bim_UInt8Image* imgA, + struct bts_Int16Rect* rectA, + uint32* meanBGGrayLevelA ); + +/** attenuates the image away from the rectangle boundary */ +void bim_ToneDownBGSupp_suppress( struct bim_UInt8Image* imgA, + struct bts_Int16Rect* rectA, + int16 rectShrinkageA, + int32 toneDownFactorA, /* bpb = [16.16] */ + int32 cutOffAccuracyA ); /* bpb = [16.16], put in 0 for highest accuracy */ + +#endif /* bim_TONE_DOWN_BG_SUPP_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/UInt16ByteImage.c b/Embedded/common/src/b_ImageEm/UInt16ByteImage.c new file mode 100644 index 0000000..e6c6ba2 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt16ByteImage.c @@ -0,0 +1,876 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/UInt16ByteImage.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_init( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA ) +{ + bbs_UInt16Arr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_exit( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA ) +{ + bbs_UInt16Arr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_copy( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.sizeE < srcPtrA->arrE.sizeE ) + { + bbs_ERROR0( "void bim_UInt16ByteImage_copy( struct bim_UInt16ByteImage*, const struct bim_UInt16ByteImage* ):\n" + "Unsufficient allocated memory in destination image" ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + bbs_UInt16Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_UInt16ByteImage_equal( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + return bbs_UInt16Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16ByteImage_checkSum( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA ) +{ + uint32 sumL =0 ; + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + const uint16* ptrL = ptrA->arrE.arrPtrE; + for( iL =0; iL < sizeL; iL++ ) + { + sumL += *ptrL++; + } + return sumL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_create( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( widthA & 1 ) + { + bbs_ERROR0( "bim_UInt16ByteImage_create( .... ): width of image must be even" ); + return; + } + + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_UInt16ByteImage_size( cpA, ptrA, widthA, heightA ); + } + else + { + bbs_UInt16Arr_create( cpA, &ptrA->arrE, ( widthA * heightA ) >> 1, mspA ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_assignExternalImage( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + struct bim_UInt16ByteImage* srcPtrA ) +{ + struct bbs_MemSeg sharedSegL = bbs_MemSeg_createShared( cpA, srcPtrA->arrE.arrPtrE, ( srcPtrA->widthE * srcPtrA->heightE ) / 2 ); + + if( ptrA->arrE.arrPtrE != 0 ) + { + bbs_ERROR0( "void bim_UInt16ByteImage_assignExternalImage( ... ): image was already created once" ); + return; + } + + bim_UInt16ByteImage_create( cpA, ptrA, + srcPtrA->widthE, + srcPtrA->heightE, + &sharedSegL ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_size( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + uint32 widthA, uint32 heightA ) +{ + if( widthA & 1 ) + { + bbs_ERROR0( "bim_UInt16ByteImage_size( .... ): width of image must be even" ); + return; + } + + if( ptrA->arrE.allocatedSizeE < ( ( widthA * heightA ) >> 1 ) ) + { + bbs_ERROR0( "void bim_UInt16ByteImage_size( struct bim_UInt16ByteImage*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } + bbs_UInt16Arr_size( cpA, &ptrA->arrE, ( widthA * heightA ) >> 1 ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16ByteImage_memSize( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_UInt16Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16ByteImage_memWrite( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_UInt16ByteImage_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_UINT16_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + bbs_UInt16Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16ByteImage_memRead( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL, widthL, heightL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT16_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &widthL, memPtrA ); + memPtrA += bbs_memRead32( &heightL, memPtrA ); + + ptrA->widthE = widthL; + ptrA->heightE = heightL; + bbs_UInt16Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_UInt16ByteImage_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt16ByteImage_memRead( const struct bim_UInt16ByteImage* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16ByteImage_setAllPixels( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + uint16 valueA ) +{ + long iL; + uint16* ptrL = ptrA->arrE.arrPtrE; + uint16 fillL = ( valueA & 0x0FF ) | ( ( valueA & 0x0FF ) << 8 ); + for( iL = ptrA->arrE.sizeE; iL > 0; iL-- ) + { + *ptrL++ = fillL; + } +} + +/* ------------------------------------------------------------------------- */ + +/** + M-------------------------------------------------------M + | | | | + | | | | + | | | | + | | | | + | region x0y0 | region x1y0 | region x2y0 | + | | | | + | | | | + | | | | + |---------------I-----------------------I---------------| + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | region x0y1 | region x1y1 | region x2y1 | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + |---------------I-----------------------I---------------| + | | | | + | | | | + | | | | + | | | | + | region x0y2 | region x1y2 | region x2y2 | + | | | | + | | | | + | | | | + M-------------------------------------------------------M + + + To see how the code is organized. Refer to the diagram above. + Assume the original image after applying the tranzformations(translation, rotation and scaling) is "O" + (boundaries of the image are shown above bounded by the letter 'O'). + This image is being Warped to the area "M" (boundaries of this area are bounded by the letter 'M'). + + Refer to the source code below to point to the loop that maps pixels in the particular region. +*/ + +/** applies affine linear warping to pixels positions of imageA before copying the into *ptrA */ +void bim_UInt16ByteImage_warp( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ) +{ + long srcWidthL = srcPtrA->widthE; + long srcHeightL = srcPtrA->heightE; + long halfSrcWidthL = srcWidthL >> 1; + + struct bts_Flt16Alt2D invAlt2DL; + + uint16* dstPtrL; + const uint16* ulPtrL = srcPtrA->arrE.arrPtrE; + const uint16* urPtrL = ulPtrL + halfSrcWidthL - 1; + const uint16* llPtrL = ulPtrL + ( srcHeightL - 1 ) * halfSrcWidthL; + const uint16* lrPtrL = llPtrL + halfSrcWidthL - 1; + + uint32 iL, jL; + int32 shiftL; + + const uint16 bbpL = 16; + int32 maxInt32Value8bbpL = 0x7FFFFFFF; + + /* The bbp for all these variables is the same as bbpL */ + int32 mxxL; + int32 mxyL; + int32 myxL; + int32 myyL; + + int32 txL; + int32 tyL; + + int32 xL; + int32 yL; + + bim_UInt16ByteImage_size( cpA, ptrA, resultWidthA, resultHeightA ); + dstPtrL = ptrA->arrE.arrPtrE; + + /* compute inverse */ + invAlt2DL = bts_Flt16Alt2D_inverted( altPtrA ); + + if( srcWidthL == 0 || srcHeightL == 0 ) + { + bim_UInt16ByteImage_size( cpA, ptrA, srcWidthL, srcHeightL ); + bbs_ERROR2( "Size of output image is %d/%d", srcWidthL, srcHeightL ); + return; + } + + /* align Matrix and Vector to 8 bits bbp */ + shiftL = invAlt2DL.matE.bbpE - bbpL; + if( shiftL >= 0 ) + { + mxxL = ( int32 )invAlt2DL.matE.xxE >> shiftL; + mxyL = ( int32 )invAlt2DL.matE.xyE >> shiftL; + myxL = ( int32 )invAlt2DL.matE.yxE >> shiftL; + myyL = ( int32 )invAlt2DL.matE.yyE >> shiftL; + } + else + { + /* Check for overflow since we are left shifting. */ + maxInt32Value8bbpL >>= -shiftL; + if( invAlt2DL.matE.xxE > maxInt32Value8bbpL || + invAlt2DL.matE.xyE > maxInt32Value8bbpL || + invAlt2DL.matE.yxE > maxInt32Value8bbpL || + invAlt2DL.matE.yyE > maxInt32Value8bbpL ) + { + /* Overflow error */ + bbs_ERROR5( "The values in the transformation matrix cause overflow during bitshift\n%d, %d,\n%d, %d\n" + "The maximum allowed value is %d", + invAlt2DL.matE.xxE >> invAlt2DL.matE.bbpE, + invAlt2DL.matE.xyE >> invAlt2DL.matE.bbpE, + invAlt2DL.matE.yxE >> invAlt2DL.matE.bbpE, + invAlt2DL.matE.yyE >> invAlt2DL.matE.bbpE, + maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); + return; + } + + mxxL = ( int32 )invAlt2DL.matE.xxE << -shiftL; + mxyL = ( int32 )invAlt2DL.matE.xyE << -shiftL; + myxL = ( int32 )invAlt2DL.matE.yxE << -shiftL; + myyL = ( int32 )invAlt2DL.matE.yyE << -shiftL; + maxInt32Value8bbpL <<= -shiftL; + } + invAlt2DL.matE.bbpE = bbpL; + + shiftL = invAlt2DL.vecE.bbpE - bbpL; + if( shiftL >= 0 ) + { + txL = ( int32 )invAlt2DL.vecE.xE >> shiftL; + tyL = ( int32 )invAlt2DL.vecE.yE >> shiftL; + } + else + { + /* Check for overflow since we are left shifting. */ + maxInt32Value8bbpL >>= -shiftL; + if( invAlt2DL.vecE.xE > maxInt32Value8bbpL || + invAlt2DL.vecE.yE > maxInt32Value8bbpL ) + { + /* Overflow error */ + bbs_ERROR3( "The values in the vector cause overflow during bitshift\n%d, %d,\n" + "The maximum allowed value is %d", + invAlt2DL.vecE.xE >> invAlt2DL.vecE.bbpE, + invAlt2DL.vecE.yE >> invAlt2DL.vecE.bbpE, + maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); + return; + } + txL = ( int32 )invAlt2DL.vecE.xE << -shiftL; + tyL = ( int32 )invAlt2DL.vecE.yE << -shiftL; + maxInt32Value8bbpL <<= -shiftL; + } + invAlt2DL.vecE.bbpE = bbpL; + + /* For each destination pixel find the correspoding source pixel by applying the inverse transformation */ + for( jL = 0; jL < ptrA->heightE; jL++ ) + { + xL = txL + mxyL * jL; + yL = tyL + myyL * jL; + for( iL = 0; iL < ptrA->widthE; iL++ ) + { + const uint16 bbpLby2L = bbpL / 2; + const int32 oneL = ( int32 )0x00000001 << bbpLby2L; + const int32 fractionOnlyL = 0xFFFFFFFF >> ( 32 - bbpL ); + uint16 dstPixelL; + + /* The bbp for all these variables is the same as bbpLby2L */ + int32 f2xL; + int32 f2yL; + int32 f1xL; + int32 f1yL; + + /* always whole numbers with a bbp of 0 */ + int32 kL, khL; + int32 lL; + + flag kEvenL; + + /* The bbpE for these variables is bbpLby2L */ + int32 valL; + + /* Get the whole numbers only and make the bbp 0. */ + kL = xL >> bbpL; + lL = yL >> bbpL; + + khL = kL >> 1; + kEvenL = !( kL & 1 ); + + /* fraction of destination pixel in the next source pixel */ + f2xL = ( xL & fractionOnlyL ) >> bbpLby2L; + f2yL = ( yL & fractionOnlyL ) >> bbpLby2L; + /* fraction of destination pixel in the current source pixel */ + f1xL = oneL - f2xL; + f1yL = oneL - f2yL; + + /* increment values for next loop */ + xL += mxxL; + yL += myxL; + + if( lL < 0 ) + { + if( kL < 0 ) + { + /* handle all pixels in region x0y0 */ + dstPixelL = *ulPtrL & 0x0FF; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y0 */ + dstPixelL = *urPtrL >> 8; + } + else + { + /* handle all pixels in region x1y0 */ + /* The bbp has shifted left by bbpLby2L */ + if( kEvenL ) + { + uint16 srcL = *( ulPtrL + khL ); + valL = f1xL * ( srcL & 0x00FF ) + f2xL * ( srcL >> 8 ); + } + else + { + valL = f1xL * ( *( ulPtrL + khL ) >> 8 ) + f2xL * ( *( ulPtrL + khL + 1 ) & 0x0FF ); + } + dstPixelL = valL >> bbpLby2L; + } + } /* if( lL < 0 ) */ + else if( lL >= srcHeightL - 1 ) + { + if( kL < 0 ) + { + /* handle all pixels in region x0y2 */ + dstPixelL = *llPtrL & 0x0FF; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y2 */ + dstPixelL = *lrPtrL >> 8; + } + else + { + /* handle all pixels in region x1y2 */ + /* The bbp has shifted left by bbpLby2L */ + if( kEvenL ) + { + uint16 srcL = *( llPtrL + khL ); + valL = f1xL * ( srcL & 0x00FF ) + f2xL * ( srcL >> 8 ); + } + else + { + valL = f1xL * ( *( llPtrL + khL ) >> 8 ) + f2xL * ( *( llPtrL + khL + 1 ) & 0x0FF ); + } + + dstPixelL = valL >> bbpLby2L; + } + } /* if( lL >= srcHeightL - 1 ) */ + else + { + const uint16* ptr1L; + const uint16* ptr2L; + + ptr1L = ulPtrL + lL * halfSrcWidthL; + /* point to the pixel in the same column */ + ptr2L = ptr1L + halfSrcWidthL; + if( kL < 0 ) + { + /* handle all pixels in region x0y1 */ + valL = f1yL * ( *ptr1L & 0x0FF ) + f2yL * ( *ptr2L & 0x0FF ); + dstPixelL = valL >> bbpLby2L; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y1 */ + valL = f1yL * ( *( ptr1L + halfSrcWidthL - 1 ) >> 8 ) + + f2yL * ( *( ptr2L + halfSrcWidthL - 1 ) >> 8 ); + dstPixelL = valL >> bbpLby2L; + } + else + { + /* assuming that bbpL = bbpLby2 * 2 */ + /* The bbp for these variables is bbpL */ + int32 v1L; + int32 v2L; + const int32 halfL = ( int32 )0x00000001 << ( bbpL - 1 ); + + /* handle all pixels in region x1y1 */ + if( kEvenL ) + { + #ifdef HW_BIG_ENDIAN + /* Our images are in byte order for big & little endian so when using a + 16bit ptr our bytes will be swapped on big endian hardware shift and mask*/ + v1L = f1xL * ( *( ptr1L + khL ) >> 8 ) + f2xL * ( *( ptr1L + khL ) & 0x0FF ); + v2L = f1xL * ( *( ptr2L + khL ) >> 8 ) + f2xL * ( *( ptr2L + khL ) & 0x0FF ); + #else + v1L = f1xL * ( *( ptr1L + khL ) & 0x0FF ) + f2xL * ( *( ptr1L + khL ) >> 8 ); + v2L = f1xL * ( *( ptr2L + khL ) & 0x0FF ) + f2xL * ( *( ptr2L + khL ) >> 8 ); + #endif + } + else + { + #ifdef HW_BIG_ENDIAN + v1L = f1xL * ( *( ptr1L + khL ) & 0x0FF ) + f2xL * ( *( ptr1L + khL + 1 ) >> 8 ); + v2L = f1xL * ( *( ptr2L + khL ) & 0x0FF ) + f2xL * ( *( ptr2L + khL + 1 ) >> 8 ); + #else + v1L = f1xL * ( *( ptr1L + khL ) >> 8 ) + f2xL * ( *( ptr1L + khL + 1 ) & 0x0FF ); + v2L = f1xL * ( *( ptr2L + khL ) >> 8 ) + f2xL * ( *( ptr2L + khL + 1 ) & 0x0FF ); + #endif + } + /* adding the half to round off the resulting value */ + valL = v1L * f1yL + v2L * f2yL + halfL; + dstPixelL = valL >> bbpL; + } + } + + if( iL & 1 ) + { + #ifdef HW_BIG_ENDIAN + *dstPtrL |= dstPixelL & 0x0FF; + #else + *dstPtrL |= dstPixelL << 8; + #endif + dstPtrL++; + } + else + { + #ifdef HW_BIG_ENDIAN + *dstPtrL = dstPixelL << 8; + #else + *dstPtrL = dstPixelL & 0x0FF; + #endif + } + + } /* iL loop */ + } /* jL loop */ + +} + +/* ------------------------------------------------------------------------- */ + +#ifndef HW_TMS320C5x /* 16bit architecture excluded */ + +void bim_UInt16ByteImage_warp8( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ) +{ + long srcWidthL = srcPtrA->widthE; + long srcHeightL = srcPtrA->heightE; + + struct bts_Flt16Alt2D invAlt2DL; + + uint8* dstPtrL; + const uint8* ulPtrL = ( const uint8* )srcPtrA->arrE.arrPtrE; + const uint8* urPtrL = ulPtrL + srcWidthL - 1; + const uint8* llPtrL = ulPtrL + ( srcHeightL - 1 ) * srcWidthL; + const uint8* lrPtrL = llPtrL + srcWidthL - 1; + + uint32 iL, jL; + int32 shiftL; + + const uint16 bbpL = 16; + int32 maxInt32Value8bbpL = 0x7FFFFFFF; + + /* The bbp for all these variables is the same as bbpL */ + int32 mxxL; + int32 mxyL; + int32 myxL; + int32 myyL; + + int32 txL; + int32 tyL; + + int32 xL; + int32 yL; + + bim_UInt16ByteImage_size( cpA, ptrA, resultWidthA, resultHeightA ); + dstPtrL = ( uint8* )ptrA->arrE.arrPtrE; + + /* compute inverse */ + invAlt2DL = bts_Flt16Alt2D_inverted( altPtrA ); + + if( srcWidthL == 0 || srcHeightL == 0 ) + { + bbs_ERROR2( "Size of output image is %d/%d", srcWidthL, srcHeightL ); + return; + } + + /* align Matrix and Vector to 8 bits bbp */ + shiftL = invAlt2DL.matE.bbpE - bbpL; + if( shiftL >= 0 ) + { + mxxL = ( int32 )invAlt2DL.matE.xxE >> shiftL; + mxyL = ( int32 )invAlt2DL.matE.xyE >> shiftL; + myxL = ( int32 )invAlt2DL.matE.yxE >> shiftL; + myyL = ( int32 )invAlt2DL.matE.yyE >> shiftL; + } + else + { + /* Check for overflow since we are left shifting. */ + maxInt32Value8bbpL >>= -shiftL; + if( invAlt2DL.matE.xxE > maxInt32Value8bbpL || + invAlt2DL.matE.xyE > maxInt32Value8bbpL || + invAlt2DL.matE.yxE > maxInt32Value8bbpL || + invAlt2DL.matE.yyE > maxInt32Value8bbpL ) + { + /* Overflow error */ + bbs_ERROR5( "The values in the transformation matrix cause overflow during bitshift\n%d, %d,\n%d, %d\n" + "The maximum allowed value is %d", + ( int32 )invAlt2DL.matE.xxE >> invAlt2DL.matE.bbpE, + ( int32 )invAlt2DL.matE.xyE >> invAlt2DL.matE.bbpE, + ( int32 )invAlt2DL.matE.yxE >> invAlt2DL.matE.bbpE, + ( int32 )invAlt2DL.matE.yyE >> invAlt2DL.matE.bbpE, + maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); + return; + } + + mxxL = ( int32 )invAlt2DL.matE.xxE << -shiftL; + mxyL = ( int32 )invAlt2DL.matE.xyE << -shiftL; + myxL = ( int32 )invAlt2DL.matE.yxE << -shiftL; + myyL = ( int32 )invAlt2DL.matE.yyE << -shiftL; + maxInt32Value8bbpL <<= -shiftL; + } + invAlt2DL.matE.bbpE = bbpL; + + shiftL = invAlt2DL.vecE.bbpE - bbpL; + if( shiftL >= 0 ) + { + txL = ( int32 )invAlt2DL.vecE.xE >> shiftL; + tyL = ( int32 )invAlt2DL.vecE.yE >> shiftL; + } + else + { + /* Check for overflow since we are left shifting. */ + maxInt32Value8bbpL >>= -shiftL; + if( invAlt2DL.vecE.xE > maxInt32Value8bbpL || + invAlt2DL.vecE.yE > maxInt32Value8bbpL ) + { + /* Overflow error */ + bbs_ERROR3( "The values in the vector cause overflow during bitshift\n%d, %d,\n" + "The maximum allowed value is %d", + invAlt2DL.vecE.xE >> invAlt2DL.vecE.bbpE, + invAlt2DL.vecE.yE >> invAlt2DL.vecE.bbpE, + maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); + return; + } + txL = ( int32 )invAlt2DL.vecE.xE << -shiftL; + tyL = ( int32 )invAlt2DL.vecE.yE << -shiftL; + maxInt32Value8bbpL <<= -shiftL; + } + invAlt2DL.vecE.bbpE = bbpL; + + /* For each destination pixel find the correspoding source pixel by applying the inverse transformation */ + for( jL = 0; jL < ptrA->heightE; jL++ ) + { + xL = txL + mxyL * jL; + yL = tyL + myyL * jL; + for( iL = 0; iL < ptrA->widthE; iL++ ) + { + const uint16 bbpLby2L = bbpL / 2; + const int32 oneL = ( int32 )0x00000001 << bbpLby2L; + const int32 fractionOnlyL = 0xFFFFFFFF >> ( 32 - bbpL ); + + /* The bbp for all these variables is the same as bbpLby2L */ + int32 f2xL; + int32 f2yL; + int32 f1xL; + int32 f1yL; + + /* always whole numbers with a bbp of 0 */ + int32 kL; + int32 lL; + + /* The bbpE for these variables is bbpLby2L */ + int32 valL; + + /* Get the whole numbers only and make the bbp 0. */ + kL = xL >> bbpL; + lL = yL >> bbpL; + + /* fraction of destination pixel in the next source pixel */ + f2xL = ( xL & fractionOnlyL ) >> bbpLby2L; + f2yL = ( yL & fractionOnlyL ) >> bbpLby2L; + /* fraction of destination pixel in the current source pixel */ + f1xL = oneL - f2xL; + f1yL = oneL - f2yL; + + /* increment values for next loop */ + xL += mxxL; + yL += myxL; + + if( lL < 0 ) + { + if( kL < 0 ) + { + /* handle all pixels in region x0y0 */ + *dstPtrL++ = *ulPtrL; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y0 */ + *dstPtrL++ = *urPtrL; + } + else + { + /* handle all pixels in region x1y0 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *( ulPtrL + kL ) * f1xL + *( ulPtrL + kL + 1 ) * f2xL; + *dstPtrL++ = valL >> bbpLby2L; + } + } /* if( lL < 0 ) */ + else if( lL >= srcHeightL - 1 ) + { + if( kL < 0 ) + { + /* handle all pixels in region x0y2 */ + *dstPtrL++ = *llPtrL; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y2 */ + *dstPtrL++ = *lrPtrL; + } + else + { + /* handle all pixels in region x1y2 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *( llPtrL + kL ) * f1xL + *( llPtrL + kL + 1 ) * f2xL; + *dstPtrL++ = valL >> bbpLby2L; + } + } /* if( lL >= srcHeightL - 1 ) */ + else + { + const uint8* ptr1L; + const uint8* ptr2L; + + ptr1L = ulPtrL + lL * srcWidthL; + /* point to the pixel in the same column */ + ptr2L = ptr1L + srcWidthL; + if( kL < 0 ) + { + /* handle all pixels in region x0y1 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *ptr1L * f1yL + *ptr2L * f2yL ; + *dstPtrL++ = valL >> bbpLby2L; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y1 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *( ptr1L + srcWidthL - 1 ) * f1yL + *( ptr2L + srcWidthL - 1 ) * f2yL; + *dstPtrL++ = valL >> bbpLby2L; + } + else + { + /* assuming that bbpL = bbpLby2 * 2 */ + /* The bbp for these variables is bbpLby2L */ + int32 v1L; + int32 v2L; + /* The bbp for these variables is bbpL */ + const int32 halfL = ( int32 )0x00000001 << ( bbpL - 1 ); + + /* handle all pixels in region x1y1 */ + /* The bbp has shifted left by bbpLby2L */ + v1L = *( ptr1L + kL ) * f1xL + *( ptr1L + kL + 1 ) * f2xL; + v2L = *( ptr2L + kL ) * f1xL + *( ptr2L + kL + 1 ) * f2xL; + /* The bbp has shifted left again by bbpLby2L */ + /* adding the half to round off the resulting value */ + valL = v1L * f1yL + v2L * f2yL + halfL; + *dstPtrL++ = valL >> bbpL; + } + } + } /* iL loop */ + } /* jL loop */ + +} + +#endif + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/UInt16ByteImage.h b/Embedded/common/src/b_ImageEm/UInt16ByteImage.h new file mode 100644 index 0000000..3e6c0c6 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt16ByteImage.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_UINT16_IMAGE_EM_H +#define bim_UINT16_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/UInt16Arr.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt2D.h" +#include "b_ImageEm/UInt8Image.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_UINT16_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** Packed byte image + * 2 pixels are stored on a 16 bit space. + * Using conventional pixel order, the first pixel is represented by the low-byte. + * A Pixel at position (x,y) can be accessed as follows: + * ( ( arrE.arrE + y * withE + ( x >> 1 ) ) >> ( 8 * ( x & 1 ) ) ) & 0x0FF; + * + * On little endian platforms bim_UInt16ByteImage and bim_UInt8Image + * have the same memory representation of the image data. + */ +struct bim_UInt16ByteImage +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** array of 16bit words */ + struct bbs_UInt16Arr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_UInt16ByteImage */ +void bim_UInt16ByteImage_init( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA ); + +/** allocates memory for bim_UInt16ByteImage */ +void bim_UInt16ByteImage_create( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ); + +/** destructor of bim_UInt16ByteImage */ +void bim_UInt16ByteImage_exit( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_UInt16ByteImage_copy( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA ); + +/** equal operator */ +flag bim_UInt16ByteImage_equal( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** checksum of image (for debugging purposes) */ +uint32 bim_UInt16ByteImage_checkSum( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** assigns external image to array (no allocation, deallocation or copying of data) */ +void bim_UInt16ByteImage_assignExternalImage( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + struct bim_UInt16ByteImage* srcPtrA ); + +/** sets image size */ +void bim_UInt16ByteImage_size( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + uint32 widthA, uint32 heightA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bim_UInt16ByteImage_memSize( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bim_UInt16ByteImage_memWrite( struct bbs_Context* cpA, + const struct bim_UInt16ByteImage* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bim_UInt16ByteImage_memRead( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets all pixels to one value; higher 8 bits of valueA are ignored */ +void bim_UInt16ByteImage_setAllPixels( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + uint16 valueA ); + +/** applies affine linear warping to pixels positions of imageA before copying the into *ptrA */ +void bim_UInt16ByteImage_warp( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ); + + +#ifndef HW_TMS320C5x /* 16bit architecture excluded */ + +/** applies affine linear warping to pixels positions of ptrA before copying the into *ptrA. + * This function accepts an bim_UInt16ByteImage as input, but uses a faster algorithm + * utilizing 8-bit data access for warping. + * Only available for platforms that allow 8 bit data access. + */ +void bim_UInt16ByteImage_warp8( struct bbs_Context* cpA, + struct bim_UInt16ByteImage* ptrA, + const struct bim_UInt16ByteImage* srcPtrA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ); +#endif /* HW_TMS320C5x */ + +#endif /* bim_UINT16_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/UInt16BytePyrImage.c b/Embedded/common/src/b_ImageEm/UInt16BytePyrImage.c new file mode 100644 index 0000000..e662f21 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt16BytePyrImage.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/Functions.h" +#include "b_ImageEm/UInt16BytePyrImage.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16BytePyrImage_init( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA ) +{ + bbs_UInt16Arr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->depthE = 0; + ptrA->typeE = bim_UINT16_PYRAMIDAL_IMG; +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16BytePyrImage_exit( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA ) +{ + bbs_UInt16Arr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->depthE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16BytePyrImage_copy( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + const struct bim_UInt16BytePyrImage* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_UInt16BytePyrImage_copy( ... ):\n" + "Unsufficient allocated memory in destination image" ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + ptrA->depthE = srcPtrA->depthE; + bbs_UInt16Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_UInt16BytePyrImage_equal( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + const struct bim_UInt16BytePyrImage* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + if( ptrA->depthE != srcPtrA->depthE ) return FALSE; + return bbs_UInt16Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint16* bim_UInt16BytePyrImage_arrPtr( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + uint32 levelA ) +{ + uint32 iL; + uint32 offsL = 0; + uint32 baseSizeL = ( ptrA->widthE * ptrA->heightE ) >> 1; + +#ifdef DEBUG2 + if( levelA >= ptrA->depthE ) + { + bbs_ERROR2( "uint16* bim_UInt16BytePyrImage_arrPtr( struct bim_UInt16BytePyrImage*, uint32 levelA ):\n" + "levelA = %i out of range [0,%i]", levelA, ptrA->depthE - 1 ); + return NULL; + } +#endif + + for( iL = 0; iL < levelA; iL++ ) + { + offsL += ( baseSizeL >> ( iL * 2 ) ); + } + return ptrA->arrE.arrPtrE + offsL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16BytePyrImage_heapSize( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + uint32 widthA, uint32 heightA, + uint32 depthA ) +{ + uint32 baseSizeL = ( widthA * heightA ) >> 1; + uint32 sizeL = 0; + uint32 iL; + for( iL = 0; iL < depthA; iL++ ) + { + sizeL += ( baseSizeL >> ( iL * 2 ) ); + } + return bbs_UInt16Arr_heapSize( cpA, &ptrA->arrE, sizeL ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16BytePyrImage_create( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + uint32 widthA, uint32 heightA, + uint32 depthA, + struct bbs_MemSeg* mspA ) +{ + uint32 baseSizeL = ( widthA * heightA ) >> 1; + uint32 sizeL = 0; + uint32 iL; + + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_UInt16BytePyrImage_size( cpA, ptrA, widthA, heightA, depthA ); + return; + } + +#ifdef DEBUG1 + { + uint32 depthMaskL = ( ( int32 )1 << ( depthA - 1 ) ) - 1; + if( depthA == 0 ) + { + bbs_ERROR0( "void bim_UInt16BytePyrImage_create( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "depthA must be > 0" ); + return; + } + if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) ) + { + bbs_ERROR1( "void bim_UInt16BytePyrImage_create( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "widthA and heightA must be divisible by %i", depthMaskL + 1 ); + return; + } + } +#endif + + ptrA->widthE = widthA; + ptrA->heightE = heightA; + ptrA->depthE = depthA; + + for( iL = 0; iL < depthA; iL++ ) + { + sizeL += ( baseSizeL >> ( iL * 2 ) ); + } + bbs_UInt16Arr_create( cpA, &ptrA->arrE, sizeL, mspA ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt16BytePyrImage_size( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ) +{ + uint32 baseSizeL = ( widthA * heightA ) >> 1; + uint32 sizeL = 0; + uint32 iL; + +#ifdef DEBUG1 + uint32 depthMaskL = ( 1 << ( depthA - 1 ) ) - 1; + if( depthA == 0 ) + { + bbs_ERROR0( "void bim_UInt16BytePyrImage_size( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "depthA must be > 0" ); + return; + } + + if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) ) + { + bbs_ERROR1( "void bim_UInt16BytePyrImage_size( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "widthA and heightA must be divisible by %i", depthMaskL + 1 ); + return; + } +#endif + + ptrA->widthE = widthA; + ptrA->heightE = heightA; + ptrA->depthE = depthA; + + for( iL = 0; iL < depthA; iL++ ) + { + sizeL += ( baseSizeL >> ( iL * 2 ) ); + } +#ifdef DEBUG1 + if( sizeL > ptrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_UInt16BytePyrImage_size( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "Insufficient allocated memory." ); + return; + } +#endif + bbs_UInt16Arr_size( cpA, &ptrA->arrE, sizeL ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16BytePyrImage_memSize( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_SIZEOF16( ptrA->depthE ) + + bbs_UInt16Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16BytePyrImage_memWrite( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_UInt16BytePyrImage_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_UINT16_PYRAMIDAL_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->depthE, memPtrA ); + bbs_UInt16Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt16BytePyrImage_memRead( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL, widthL, heightL, depthL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT16_PYRAMIDAL_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &widthL, memPtrA ); + memPtrA += bbs_memRead32( &heightL, memPtrA ); + memPtrA += bbs_memRead32( &depthL, memPtrA ); + + ptrA->widthE = widthL; + ptrA->heightE = heightL; + ptrA->depthE = depthL; + bbs_UInt16Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_UInt16BytePyrImage_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt16BytePyrImage_memRead( const struct bim_UInt16BytePyrImage* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +void bim_UInt16BytePyrImage_overlayUInt16( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + struct bim_UInt16ByteImage* uint16ImageA ) +{ + uint16ImageA->widthE = ptrA->widthE; + uint16ImageA->heightE = ptrA->heightE; + uint16ImageA->arrE.sizeE = ptrA->widthE * ptrA->heightE; + uint16ImageA->arrE.allocatedSizeE = ptrA->widthE * ptrA->heightE; + uint16ImageA->arrE.arrPtrE = ptrA->arrE.arrPtrE; + uint16ImageA->arrE.mspE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/** process remaining layers */ +void bim_UInt16BytePyrImage_recompute( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* dstPtrA ) +{ + count_t iL, jL, layerL; + uint16 tmpL; + + uint32 widthL = dstPtrA->widthE; + uint32 halfWidthL = widthL >> 1; + uint32 heightL = dstPtrA->heightE; + + uint16* srcL = dstPtrA->arrE.arrPtrE; + uint16* dstL = srcL + ( heightL * halfWidthL ); + for( layerL = 1; layerL < dstPtrA->depthE; layerL++ ) + { + for( jL = ( heightL >> 1 ); jL > 0; jL-- ) + { + for( iL = ( halfWidthL >> 1 ); iL > 0; iL-- ) + { + /* averaging with rounding */ + tmpL = ( ( *srcL & 0x0FF ) + ( *srcL >> 8 ) + ( *( srcL + halfWidthL ) & 0x0FF ) + + ( *( srcL + halfWidthL ) >> 8 ) + 2 ) >> 2; + #ifdef HW_BIG_ENDIAN + *dstL = tmpL << 8; + #else + *dstL = tmpL; + #endif + srcL++; + + tmpL = ( ( *srcL & 0x0FF ) + ( *srcL >> 8 ) + ( *( srcL + halfWidthL ) & 0x0FF ) + + ( *( srcL + halfWidthL ) >> 8 ) + 2 ) >> 2; + #ifdef HW_BIG_ENDIAN + *dstL |= tmpL; + #else + *dstL |= tmpL << 8; + #endif + srcL++; + dstL++; + } + srcL += halfWidthL; + } + halfWidthL >>= 1; + heightL >>= 1; + } +} + + +/* ------------------------------------------------------------------------- */ + + +void bim_UInt16BytePyrImage_importUInt16( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* dstPtrA, + const struct bim_UInt16ByteImage* srcPtrA, + uint32 depthA ) +{ + + bim_UInt16BytePyrImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE, depthA ); + + /* copy first layer */ + bbs_memcpy16( dstPtrA->arrE.arrPtrE, srcPtrA->arrE.arrPtrE, srcPtrA->arrE.sizeE ); + + bim_UInt16BytePyrImage_recompute( cpA, dstPtrA ); +} + + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/UInt16BytePyrImage.h b/Embedded/common/src/b_ImageEm/UInt16BytePyrImage.h new file mode 100644 index 0000000..168baeb --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt16BytePyrImage.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_UINT16_PYR_IMAGE_EM_H +#define bim_UINT16_PYR_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_ImageEm/UInt16ByteImage.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +#define bim_PYRAMIDAL_IMAGE_STANDARD_DEPTH 4 + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_UINT16_PYRAMIDAL_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** Pyramidal image of uint16 (packed bytes). + * + * 2 pixels are stored in one 16-bit word. On a little endian system the + * image data of bim_UInt16BytePyrImage and bim_UInt8PyramidalImage have + * an identical memory representation. + * + * The Pyramidal format is as follows: + * widthE specifies width of first image (image 0) + * heightE specifies height of first image (image 0) + * depthE specifies the number of levels present + * image n has half of the width,heigth nimension of image n-1 + * A pixel of in image n is the average of the corresponding 4 + * covering pixels in image n-1 + * Adresses of data relative to arrE.arrPtrE + * The address of image 0 is 0 + * The address of image 1 is widthE * heightE / 2 + * The address of image n is widthE * heightE / 2 + widthE * heightE / 8 + ... + widthE * heightE * ( 2^-(2*n) ) + * Use function uint16* bim_UInt16BytePyrImage_arrPtr( uint32 levelA ) to obtain adress of image at given depth level + * Use function bim_UInt16BytePyrImage_importUInt8 to create a pyramidal image from an uint8 image +*/ +struct bim_UInt16BytePyrImage +{ + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** depth of image (number of layers) */ + uint32 depthE; + + /** pyramidal image type (temporary: until switch to 16-bit complete) */ + uint32 typeE; + + /** array of bytes */ + struct bbs_UInt16Arr arrE; +}; + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_UInt16BytePyrImage */ +void bim_UInt16BytePyrImage_init( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA ); + +/** allocates memory for bim_UInt16BytePyrImage */ +void bim_UInt16BytePyrImage_create( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + uint32 widthA, uint32 heightA, + uint32 depthA, + struct bbs_MemSeg* mspA ); + +/** frees bim_UInt16BytePyrImage */ +void bim_UInt16BytePyrImage_exit( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_UInt16BytePyrImage_copy( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + const struct bim_UInt16BytePyrImage* srcPtrA ); + +/** equal operator */ +flag bim_UInt16BytePyrImage_equal( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + const struct bim_UInt16BytePyrImage* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns adress of image at given depth level */ +uint16* bim_UInt16BytePyrImage_arrPtr( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + uint32 levelA ); + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bim_UInt16BytePyrImage_heapSize( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** sets image size */ +void bim_UInt16BytePyrImage_size( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bim_UInt16BytePyrImage_memSize( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bim_UInt16BytePyrImage_memWrite( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bim_UInt16BytePyrImage_memRead( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** create overlay bim_Uint16Image (does not own memory) */ +void bim_UInt16BytePyrImage_overlayUInt16( struct bbs_Context* cpA, + const struct bim_UInt16BytePyrImage* ptrA, + struct bim_UInt16ByteImage* uint16ImageA ); + +/** recompute pyramidal format with given depth from data in layer 0 */ +void bim_UInt16BytePyrImage_recompute( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* dstPtrA ); + +/** import uint8image and creates pyramidal format with given depth */ +void bim_UInt16BytePyrImage_importUInt16( struct bbs_Context* cpA, + struct bim_UInt16BytePyrImage* dstPtrA, + const struct bim_UInt16ByteImage* srcPtrA, + uint32 depthA ); + +#endif /* bim_UINT16_PYR_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/UInt32Image.c b/Embedded/common/src/b_ImageEm/UInt32Image.c new file mode 100644 index 0000000..771f0b8 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt32Image.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/UInt32Image.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_init( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA ) +{ + bbs_UInt32Arr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_exit( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA ) +{ + bbs_UInt32Arr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_copy( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + const struct bim_UInt32Image* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_UInt32Image_copy(...):\n" + "Unsufficient allocated memory in destination image." ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + bbs_UInt32Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_UInt32Image_equal( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA, + const struct bim_UInt32Image* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + return bbs_UInt32Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt32Image_heapSize( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA, + uint32 widthA, + uint32 heightA ) +{ + return bbs_UInt32Arr_heapSize( cpA, &ptrA->arrE, widthA * heightA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt32Image_checkSum( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA ) +{ + uint32 sumL =0 ; + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + const uint32* ptrL = ptrA->arrE.arrPtrE; + for( iL =0; iL < sizeL; iL++ ) + { + sumL += *ptrL++; + } + return sumL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_create( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_UInt32Image_size( cpA, ptrA, widthA, heightA ); + } + else + { + bbs_UInt32Arr_create( cpA, &ptrA->arrE, widthA * heightA, mspA ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_assignExternalImage( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + struct bim_UInt32Image* srcPtrA ) +{ + struct bbs_MemSeg sharedSegL = bbs_MemSeg_createShared( cpA, srcPtrA->arrE.arrPtrE, srcPtrA->widthE * srcPtrA->heightE ); + + if( ptrA->arrE.arrPtrE != 0 ) + { + bbs_ERROR0( "void bim_UInt32Image_assignExternalImage( ... ): image was already created once" ); + return; + } + + bim_UInt32Image_create( cpA, + ptrA, + srcPtrA->widthE, + srcPtrA->heightE, + &sharedSegL ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_size( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + uint32 widthA, + uint32 heightA ) +{ + if( ptrA->arrE.allocatedSizeE < widthA * heightA ) + { + bbs_ERROR0( "void bim_UInt32Image_size( struct bim_UInt32Image*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } + ptrA->widthE = widthA; + ptrA->heightE = heightA; + bbs_UInt32Arr_size( cpA, &ptrA->arrE, widthA * heightA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt32Image_memSize( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_UInt32Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt32Image_memWrite( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_UInt32Image_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_UINT32_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + bbs_UInt32Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt32Image_memRead( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT32_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->heightE, memPtrA ); + bbs_UInt32Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_UInt32Image_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt32Image_memRead( const struct bim_UInt32Image* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt32Image_setAllPixels( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + uint32 valueA, + int32 bbpA ) +{ + long iL; + uint32* ptrL = ptrA->arrE.arrPtrE; + for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- ) + { + *ptrL++ = valueA; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/UInt32Image.h b/Embedded/common/src/b_ImageEm/UInt32Image.h new file mode 100644 index 0000000..3d56656 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt32Image.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_UINT32_IMAGE_EM_H +#define bim_UINT32_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/UInt32Arr.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_UINT32_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** image of uint32 */ +struct bim_UInt32Image +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** array of bytes */ + struct bbs_UInt32Arr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_UInt32Image */ +void bim_UInt32Image_init( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA ); + +/** destroys bim_UInt32Image */ +void bim_UInt32Image_exit( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_UInt32Image_copy( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + const struct bim_UInt32Image* srcPtrA ); + +/** equal operator */ +flag bim_UInt32Image_equal( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA, + const struct bim_UInt32Image* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bim_UInt32Image_heapSize( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA, + uint32 widthA, + uint32 heightA ); + +/** checksum of image (for debugging purposes) */ +uint32 bim_UInt32Image_checkSum( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates memory for bim_UInt32Image */ +void bim_UInt32Image_create( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ); + +/** assigns external image to array (no allocation, deallocation or copying of data) */ +void bim_UInt32Image_assignExternalImage( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + struct bim_UInt32Image* srcPtrA ); + +/** sets image size */ +void bim_UInt32Image_size( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + uint32 widthA, + uint32 heightA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) needs when written to memory */ +uint32 bim_UInt32Image_memSize( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bim_UInt32Image_memWrite( struct bbs_Context* cpA, + const struct bim_UInt32Image* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bim_UInt32Image_memRead( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets all pixels to one value */ +void bim_UInt32Image_setAllPixels( struct bbs_Context* cpA, + struct bim_UInt32Image* ptrA, + uint32 valueA, + int32 bbpA ); + +#endif /* bim_UINT32_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/UInt8Image.c b/Embedded/common/src/b_ImageEm/UInt8Image.c new file mode 100644 index 0000000..39af7ca --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt8Image.c @@ -0,0 +1,777 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/UInt8Image.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_init( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA ) +{ + bbs_UInt8Arr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_create( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_UInt8Image_size( cpA, ptrA, widthA, heightA ); + } + else + { + bbs_UInt8Arr_create( cpA, &ptrA->arrE, widthA * heightA, mspA ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; + } +} +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_exit( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA ) +{ + bbs_UInt8Arr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_copy( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.sizeE < srcPtrA->arrE.sizeE ) + { + bbs_ERROR0( "void bim_UInt8Image_copy( struct bim_UInt8Image*, const struct bim_UInt8Image* ):\n" + "Unsufficient allocated memory in destination image" ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + bbs_UInt8Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_UInt8Image_equal( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + return bbs_UInt8Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8Image_checkSum( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA ) +{ + uint32 sumL =0 ; + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + const uint8* ptrL = ptrA->arrE.arrPtrE; + for( iL =0; iL < sizeL; iL++ ) + { + sumL += *ptrL++; + } + return sumL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_assignExternalImage( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + struct bim_UInt8Image* srcPtrA ) +{ + struct bbs_MemSeg sharedSegL = bbs_MemSeg_createShared( cpA, srcPtrA->arrE.arrPtrE, ( srcPtrA->widthE * srcPtrA->heightE ) / 2 ); + + if( ptrA->arrE.arrPtrE != 0 ) + { + bbs_ERROR0( "void bim_UInt8Image_assignExternalImage( ... ): image was already created once" ); + return; + } + + bim_UInt8Image_create( cpA, ptrA, + srcPtrA->widthE, + srcPtrA->heightE, + &sharedSegL ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_size( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + uint32 widthA, + uint32 heightA ) +{ + if( ptrA->arrE.allocatedSizeE < widthA * heightA ) + { + bbs_ERROR0( "void bim_UInt8Image_size( struct bim_UInt8Image*, uint32 sizeA ):\n" + "Unsufficient allocated memory" ); + return; + } + bbs_UInt8Arr_size( cpA, &ptrA->arrE, widthA * heightA ); + ptrA->widthE = widthA; + ptrA->heightE = heightA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8Image_memSize( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_UInt8Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8Image_memWrite( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_UInt8Image_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_UINT8_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + bbs_UInt8Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8Image_memRead( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL, widthL, heightL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT8_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &widthL, memPtrA ); + memPtrA += bbs_memRead32( &heightL, memPtrA ); + + ptrA->widthE = widthL; + ptrA->heightE = heightL; + bbs_UInt8Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_UInt8Image_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt8Image_memRead( const struct bim_UInt8Image* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_setAllPixels( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + uint8 valueA ) +{ + long iL; + uint8* ptrL = ptrA->arrE.arrPtrE; + for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- ) + { + *ptrL++ = valueA; + } +} + +/* ------------------------------------------------------------------------- */ + +/** + | | | | + | (loop x1) | (loop x2) | (loop x3) | + o------------->-o------------>--o------------->-o + | | | | + | | | | + | | | | + | | | | + ( sectionL->x1E, sectionL->y1E ) | | +---------o- R-------------------------------|---------------- + | | | | | + | | | | | + | | | | | + | | | | | + (loop y1)| | | | + | | | | | + V | | | | + | | |( 0, 0 ) | | X +---------o------------------I-------------------------------------------------> + | | | | | + | | | | | + | | | | | + | | | | | + | | | | | + (loop y2)| | | | + | | | | | + | | | | | + | | | | | + V | | | | + | | | | | +---------o------------------|---------------I | + | | | ( srcPtrA->widthE, srcPtrA->heightE ) + | | | | + | | | | + | | | | + | | | | + | | | | + (loop y3)| | | + | | | | + | | | | + V | | | + | | | | +---------o--------------------------------------------------R + | ( sectionL->x2E, sectionL->y2E ) + | + Y | + | + | + V + + To understand how the algorithm work refer to the diagram above. + The image boundaries are indicated by letter "I" ( 0, 0 ) to ( srcPtrA->widthE, srcPtrA->heightE ) + The rectangle boundaries are indicated by letter "R" ( sectionPtrA->x1E, sectionPtrA->y1E ) to ( sectionPtrA->x2E, sectionPtrA->y2E ) + + In the above example the intersection of the image and the rectange is + ( 0, 0 ), ( srcPtrA->widthE, srcPtrA->heightE ) + + The size of the destination image is always ( ( sectionL->x2E, sectionL->y2E ) - ( sectionL->x1E, sectionL->y1E ) ) + + All coordinates are assumed to be relative to the original image. + + 1. parse all pixels in "loop y1" + 1.a. parse all pixels in "loop x1" + 1.b. parse all pixels in "loop x2" + 1.c. parse all pixels in "loop x3" + 2. parse all pixels in "loop y2" + 2.a. parse all pixels in "loop x1" + 2.b. parse all pixels in "loop x2" + 2.c. parse all pixels in "loop x3" + 3. parse all pixels in "loop y3" + 3.a. parse all pixels in "loop x1" + 3.b. parse all pixels in "loop x2" + 3.c. parse all pixels in "loop x3" + +*/ + +/** copies a section of given image */ +void bim_UInt8Image_copySection( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ) +{ + + uint8* srcPixelPtrL; + uint8* dstPixelPtrL; + int32 yIndexL; + int32 xIndexL; + + struct bts_Int16Rect srcImageSubSectionL; + struct bts_Int16Rect sectionL; + + /* make sure that the rectangle passed is correct, in case the x2 < x1 or y2 < y1, swap them */ + sectionL.x1E = bbs_min( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.x2E = bbs_max( sectionPtrA->x1E, sectionPtrA->x2E ); + sectionL.y1E = bbs_min( sectionPtrA->y1E, sectionPtrA->y2E ); + sectionL.y2E = bbs_max( sectionPtrA->y1E, sectionPtrA->y2E ); + + /* find the intersection betweem the rectangle and the image, the image always starts at 0,0 */ + srcImageSubSectionL.x1E = bbs_max( 0, sectionL.x1E ); + srcImageSubSectionL.y1E = bbs_max( 0, sectionL.y1E ); + srcImageSubSectionL.x2E = bbs_min( ( int32 ) srcPtrA->widthE, sectionL.x2E ); + srcImageSubSectionL.y2E = bbs_min( ( int32 ) srcPtrA->heightE, sectionL.y2E ); + + /* If the image and the rectangle do not intersect in X direction, set the intersecting rectangle to the image coordinates */ + if( srcImageSubSectionL.x2E < srcImageSubSectionL.x1E ) + { + srcImageSubSectionL.x1E = 0; + srcImageSubSectionL.x2E = srcPtrA->widthE; + } + /* do the same as above in the Y direction */ + if( srcImageSubSectionL.y2E < srcImageSubSectionL.y1E ) + { + srcImageSubSectionL.y1E = 0; + srcImageSubSectionL.y2E = srcPtrA->heightE; + } + + /* set size, and allocate required memory for the destination image if required */ + bim_UInt8Image_size( cpA, ptrA, sectionL.x2E - sectionL.x1E, sectionL.y2E - sectionL.y1E ); + + /* get the pointer to the destination image */ + dstPixelPtrL = ptrA->arrE.arrPtrE; + + /* 1. parse all pixels in "loop y1" */ + for( yIndexL = sectionL.y1E; yIndexL < srcImageSubSectionL.y1E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE; + + /* 1.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 1.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 1.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 2. parse all pixels in "loop y2" */ + for( ; yIndexL < srcImageSubSectionL.y2E && yIndexL < sectionL.y2E; yIndexL++ ) + { + /* move to the first pixel that needs to be copied. */ + srcPixelPtrL = srcPtrA->arrE.arrPtrE + yIndexL * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 2.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 2.b. parse all pixels in "loop x2" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 2.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + /* 3. parse all pixels in "loop y3" */ + for( ; yIndexL < sectionL.y2E; yIndexL++ ) + { + srcPixelPtrL = srcPtrA->arrE.arrPtrE + ( srcImageSubSectionL.y2E - 1 ) * srcPtrA->widthE + srcImageSubSectionL.x1E; + + /* 3.a. parse all pixels in "loop x1" */ + for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + /* 3.b. parse all pixels in "loop x3" */ + for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL++; + } + srcPixelPtrL--; + /* 3.c. parse all pixels in "loop x3" */ + for( ; xIndexL < sectionL.x2E; xIndexL++ ) + { + *dstPixelPtrL++ = *srcPixelPtrL; + } + } + +} + +/* ------------------------------------------------------------------------- */ + +/** + + + M-------------------------------------------------------M + | | | | + | | | | + | | | | + | | | | + | region x0y0 | region x1y0 | region x2y0 | + | | | | + | | | | + | | | | + |---------------I-----------------------I---------------| + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | region x0y1 | region x1y1 | region x2y1 | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + |---------------I-----------------------I---------------| + | | | | + | | | | + | | | | + | | | | + | region x0y2 | region x1y2 | region x2y2 | + | | | | + | | | | + | | | | + M-------------------------------------------------------M + + + To see how the code is organized. Refer to the diagram above. + Assume the original image after applying the tranzformations(translation, rotation and scaling) is "O" + (boundaries of the image are shown above bounded by the letter 'O'). + This image is being Warped to the area "M" (boundaries of this area are bounded by the letter 'M'). + + Refer to the source code below to point to the loop that maps pixels in the particular region. + + */ + +/** applies affine linear warping to pixels positions of imageA before copying the into *ptrA */ +void bim_UInt8Image_warpOffs( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA, + int32 xOffsA, + int32 yOffsA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ) +{ + long srcWidthL = srcPtrA->widthE; + long srcHeightL = srcPtrA->heightE; + + struct bts_Flt16Alt2D invAlt2DL; + + uint8* dstPtrL; + const uint8* ulPtrL = srcPtrA->arrE.arrPtrE; + const uint8* urPtrL = ulPtrL + srcWidthL - 1; + const uint8* llPtrL = ulPtrL + ( srcHeightL - 1 ) * srcWidthL; + const uint8* lrPtrL = llPtrL + srcWidthL - 1; + + uint32 iL, jL; + int32 shiftL; + + const uint16 bbpL = 16; + int32 maxInt32Value8bbpL = 0x7FFFFFFF; + + /* The bbp for all these variables is the same as bbpL */ + int32 mxxL; + int32 mxyL; + int32 myxL; + int32 myyL; + + int32 txL; + int32 tyL; + + int32 xL; + int32 yL; + + bim_UInt8Image_size( cpA, ptrA, resultWidthA, resultHeightA ); + dstPtrL = ptrA->arrE.arrPtrE; + + /* compute inverse */ + invAlt2DL = bts_Flt16Alt2D_inverted( altPtrA ); + + if( srcWidthL == 0 || srcHeightL == 0 ) + { + bim_UInt8Image_size( cpA, ptrA, srcWidthL, srcHeightL ); + bbs_ERROR2( "Size of output image is %d/%d", srcWidthL, srcHeightL ); + return; + } + + /* align Matrix and Vector to 8 bits bbp */ + shiftL = invAlt2DL.matE.bbpE - bbpL; + if( shiftL >= 0 ) + { + mxxL = invAlt2DL.matE.xxE >> shiftL; + mxyL = invAlt2DL.matE.xyE >> shiftL; + myxL = invAlt2DL.matE.yxE >> shiftL; + myyL = invAlt2DL.matE.yyE >> shiftL; + } + else + { + /* Check for overflow since we are left shifting. */ + maxInt32Value8bbpL >>= -shiftL; + if( invAlt2DL.matE.xxE > maxInt32Value8bbpL || + invAlt2DL.matE.xyE > maxInt32Value8bbpL || + invAlt2DL.matE.yxE > maxInt32Value8bbpL || + invAlt2DL.matE.yyE > maxInt32Value8bbpL ) + { + /* Overflow error */ + bbs_ERROR5( "The values in the transformation matrix cause overflow during bitshift\n%d, %d,\n%d, %d\n" + "The maximum allowed value is %d", + invAlt2DL.matE.xxE >> invAlt2DL.matE.bbpE, + invAlt2DL.matE.xyE >> invAlt2DL.matE.bbpE, + invAlt2DL.matE.yxE >> invAlt2DL.matE.bbpE, + invAlt2DL.matE.yyE >> invAlt2DL.matE.bbpE, + maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); + return; + } + + mxxL = invAlt2DL.matE.xxE << -shiftL; + mxyL = invAlt2DL.matE.xyE << -shiftL; + myxL = invAlt2DL.matE.yxE << -shiftL; + myyL = invAlt2DL.matE.yyE << -shiftL; + maxInt32Value8bbpL <<= -shiftL; + } + + /* invAlt2DL.matE.bbpE = bbpL; nonsense! */ + + shiftL = invAlt2DL.vecE.bbpE - bbpL; + if( shiftL >= 0 ) + { + txL = invAlt2DL.vecE.xE >> shiftL; + tyL = invAlt2DL.vecE.yE >> shiftL; + } + else + { + /* Check for overflow since we are left shifting. */ + maxInt32Value8bbpL >>= -shiftL; + if( invAlt2DL.vecE.xE > maxInt32Value8bbpL || + invAlt2DL.vecE.yE > maxInt32Value8bbpL ) + { + /* Overflow error */ + bbs_ERROR3( "The values in the vector cause overflow during bitshift\n%d, %d,\n" + "The maximum allowed value is %d", + invAlt2DL.vecE.xE >> invAlt2DL.vecE.bbpE, + invAlt2DL.vecE.yE >> invAlt2DL.vecE.bbpE, + maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); + return; + } + txL = invAlt2DL.vecE.xE << -shiftL; + tyL = invAlt2DL.vecE.yE << -shiftL; + maxInt32Value8bbpL <<= -shiftL; + } + + /* invAlt2DL.vecE.bbpE = bbpL; nonsense! */ + + /* adjust offset */ + txL += xOffsA << bbpL; + tyL += yOffsA << bbpL; + + /* For each destination pixel find the correspoding source pixel by applying the inverse transformation */ + for( jL = 0; jL < ptrA->heightE; jL++ ) + { + xL = txL + mxyL * jL; + yL = tyL + myyL * jL; + for( iL = 0; iL < ptrA->widthE; iL++ ) + { + const uint16 bbpLby2L = bbpL / 2; + const int32 oneL = 0x00000001 << bbpLby2L; + const int32 fractionOnlyL = 0xFFFFFFFF >> ( 32 - bbpL ); + + /* The bbp for all these variables is the same as bbpLby2L */ + int32 f2xL; + int32 f2yL; + int32 f1xL; + int32 f1yL; + + /* always whole numbers with a bbp of 0 */ + int32 kL; + int32 lL; + + /* The bbpE for these variables is bbpLby2L */ + int32 valL; + + /* Get the whole numbers only and make the bbp 0. */ + kL = xL >> bbpL; + lL = yL >> bbpL; + + /* fraction of destination pixel in the next source pixel */ + f2xL = ( xL & fractionOnlyL ) >> bbpLby2L; + f2yL = ( yL & fractionOnlyL ) >> bbpLby2L; + /* fraction of destination pixel in the current source pixel */ + f1xL = oneL - f2xL; + f1yL = oneL - f2yL; + + /* increment values for next loop */ + xL += mxxL; + yL += myxL; + + if( lL < 0 ) + { + if( kL < 0 ) + { + /* handle all pixels in region x0y0 */ + *dstPtrL++ = *ulPtrL; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y0 */ + *dstPtrL++ = *urPtrL; + } + else + { + /* handle all pixels in region x1y0 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *( ulPtrL + kL ) * f1xL + *( ulPtrL + kL + 1 ) * f2xL; + *dstPtrL++ = valL >> bbpLby2L; + } + } /* if( lL < 0 ) */ + else if( lL >= srcHeightL - 1 ) + { + if( kL < 0 ) + { + /* handle all pixels in region x0y2 */ + *dstPtrL++ = *llPtrL; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y2 */ + *dstPtrL++ = *lrPtrL; + } + else + { + /* handle all pixels in region x1y2 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *( llPtrL + kL ) * f1xL + *( llPtrL + kL + 1 ) * f2xL; + *dstPtrL++ = valL >> bbpLby2L; + } + } /* if( lL >= srcHeightL - 1 ) */ + else + { + const uint8* ptr1L; + const uint8* ptr2L; + + ptr1L = ulPtrL + lL * srcWidthL; + /* point to the pixel in the same column */ + ptr2L = ptr1L + srcWidthL; + if( kL < 0 ) + { + /* handle all pixels in region x0y1 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *ptr1L * f1yL + *ptr2L * f2yL ; + *dstPtrL++ = valL >> bbpLby2L; + } + else if( kL >= srcWidthL - 1 ) + { + /* handle all pixels in region x2y1 */ + /* The bbp has shifted left by bbpLby2L */ + valL = *( ptr1L + srcWidthL - 1 ) * f1yL + *( ptr2L + srcWidthL - 1 ) * f2yL; + *dstPtrL++ = valL >> bbpLby2L; + } + else + { + /* assuming that bbpL = bbpLby2 * 2 */ + /* The bbp for these variables is bbpLby2L */ + int32 v1L; + int32 v2L; + /* The bbp for these variables is bbpL */ + const int32 halfL = 0x00000001 << ( bbpL - 1 ); + + /* handle all pixels in region x1y1 */ + /* The bbp has shifted left by bbpLby2L */ + v1L = *( ptr1L + kL ) * f1xL + *( ptr1L + kL + 1 ) * f2xL; + v2L = *( ptr2L + kL ) * f1xL + *( ptr2L + kL + 1 ) * f2xL; + /* The bbp has shifted left again by bbpLby2L */ + /* adding the half to round off the resulting value */ + valL = v1L * f1yL + v2L * f2yL + halfL; + *dstPtrL++ = valL >> bbpL; + } + } + } /* iL loop */ + } /* jL loop */ + +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8Image_warp( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ) +{ + bim_UInt8Image_warpOffs( cpA, ptrA, srcPtrA, 0, 0, altPtrA, resultWidthA, resultHeightA ); +} + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/UInt8Image.h b/Embedded/common/src/b_ImageEm/UInt8Image.h new file mode 100644 index 0000000..4666d5b --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt8Image.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_UINT8_IMAGE_EM_H +#define bim_UINT8_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/UInt8Arr.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_UINT8_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** image of uint8 */ +struct bim_UInt8Image +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** array of bytes */ + struct bbs_UInt8Arr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_UInt8Image */ +void bim_UInt8Image_init( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA ); + +/** allocates memory for bim_UInt8Image */ +void bim_UInt8Image_create( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + uint32 widthA, + uint32 heightA, + struct bbs_MemSeg* mspA ); + +/** destructor of bim_UInt8Image */ +void bim_UInt8Image_exit( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_UInt8Image_copy( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA ); + +/** equal operator */ +flag bim_UInt8Image_equal( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** checksum of image (for debugging purposes) */ +uint32 bim_UInt8Image_checkSum( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** assigns external image to array (no allocation, deallocation or copying of data) */ +void bim_UInt8Image_assignExternalImage( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + struct bim_UInt8Image* srcPtrA ); + +/** sets image size */ +void bim_UInt8Image_size( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + uint32 widthA, + uint32 heightA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bim_UInt8Image_memSize( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bim_UInt8Image_memWrite( struct bbs_Context* cpA, + const struct bim_UInt8Image* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bim_UInt8Image_memRead( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** sets all pixels to one value */ +void bim_UInt8Image_setAllPixels( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + uint8 valueA ); + +/** copies a section of given image */ +void bim_UInt8Image_copySection( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA, + const struct bts_Int16Rect* sectionPtrA ); + +/** applies affine linear warping to pixels positions of imageA before copying the into *ptrA + * xOffsA, yOffsA specify an additional offset vector (16.0) that is added to image coordinates + */ +void bim_UInt8Image_warpOffs( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA, + int32 xOffsA, + int32 yOffsA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ); + +/** applies affine linear warping to pixels positions of imageA before copying the into *ptrA */ +void bim_UInt8Image_warp( struct bbs_Context* cpA, + struct bim_UInt8Image* ptrA, + const struct bim_UInt8Image* srcPtrA, + const struct bts_Flt16Alt2D* altPtrA, + int32 resultWidthA, + int32 resultHeightA ); + +#endif /* bim_UINT8_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_ImageEm/UInt8PyramidalImage.c b/Embedded/common/src/b_ImageEm/UInt8PyramidalImage.c new file mode 100644 index 0000000..9b47188 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt8PyramidalImage.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_ImageEm/Functions.h" +#include "b_ImageEm/UInt8PyramidalImage.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_init( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA ) +{ + bbs_UInt8Arr_init( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->depthE = 0; + ptrA->typeE = bim_UINT8_PYRAMIDAL_IMG; +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_exit( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA ) +{ + bbs_UInt8Arr_exit( cpA, &ptrA->arrE ); + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->depthE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_copy( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + const struct bim_UInt8PyramidalImage* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_UInt8PyramidalImage_copy( ... ):\n" + "Unsufficient allocated memory in destination image" ); + return; + } +#endif + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + ptrA->depthE = srcPtrA->depthE; + bbs_UInt8Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bim_UInt8PyramidalImage_equal( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + const struct bim_UInt8PyramidalImage* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) return FALSE; + if( ptrA->heightE != srcPtrA->heightE ) return FALSE; + if( ptrA->depthE != srcPtrA->depthE ) return FALSE; + return bbs_UInt8Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint8* bim_UInt8PyramidalImage_arrPtr( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + uint32 levelA ) +{ + uint32 iL; + uint32 offsL = 0; + uint32 baseSizeL = ptrA->widthE * ptrA->heightE; + +#ifdef DEBUG2 + if( levelA >= ptrA->depthE ) + { + bbs_ERROR2( "uint8* bim_UInt8PyramidalImage_arrPtr( struct bim_UInt8PyramidalImage* ptrA, uint32 levelA ):\n" + "levelA = %i out of range [0,%i]", levelA, ptrA->depthE - 1 ); + return NULL; + } +#endif + + for( iL = 0; iL < levelA; iL++ ) + { + offsL += ( baseSizeL >> ( iL * 2 ) ); + } + return ptrA->arrE.arrPtrE + offsL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8PyramidalImage_heapSize( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ) +{ + uint32 baseSizeL = widthA * heightA; + uint32 sizeL = 0; + uint32 iL; + for( iL = 0; iL < depthA; iL++ ) + { + sizeL += ( baseSizeL >> ( iL * 2 ) ); + } + return bbs_UInt8Arr_heapSize( cpA, &ptrA->arrE, sizeL ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_create( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + uint32 widthA, uint32 heightA, + uint32 depthA, + struct bbs_MemSeg* mspA ) +{ + uint32 baseSizeL = widthA * heightA; + uint32 sizeL = 0; + uint32 iL; + if( bbs_Context_error( cpA ) ) return; + for( iL = 0; iL < depthA; iL++ ) + { + sizeL += ( baseSizeL >> ( iL * 2 ) ); + } + + if( ptrA->arrE.arrPtrE != 0 ) + { + bim_UInt8PyramidalImage_size( cpA, ptrA, widthA, heightA, depthA ); + return; + } + +#ifdef DEBUG1 + { + uint32 depthMaskL = ( 1 << ( depthA - 1 ) ) - 1; + if( depthA == 0 ) + { + bbs_ERROR0( "void bim_UInt8PyramidalImage_create( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "depthA must be > 0" ); + return; + } + if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) ) + { + bbs_ERROR1( "void bim_UInt8PyramidalImage_create( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "widthA and heightA must be divisible by %i", depthMaskL + 1 ); + return; + } + } +#endif + + ptrA->widthE = widthA; + ptrA->heightE = heightA; + ptrA->depthE = depthA; + + bbs_UInt8Arr_create( cpA, &ptrA->arrE, sizeL, mspA ); +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_size( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ) +{ + uint32 baseSizeL = widthA * heightA; + uint32 sizeL = 0; + uint32 iL; + +#ifdef DEBUG1 + uint32 depthMaskL = ( 1 << ( depthA - 1 ) ) - 1; + if( depthA == 0 ) + { + bbs_ERROR0( "void bim_UInt8PyramidalImage_size( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "depthA must be > 0" ); + return; + } + + if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) ) + { + bbs_ERROR1( "void bim_UInt8PyramidalImage_size( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "widthA and heightA must be divisible by %i", depthMaskL + 1 ); + return; + } +#endif + + ptrA->widthE = widthA; + ptrA->heightE = heightA; + ptrA->depthE = depthA; + + for( iL = 0; iL < depthA; iL++ ) + { + sizeL += ( baseSizeL >> ( iL * 2 ) ); + } +#ifdef DEBUG1 + if( sizeL > ptrA->arrE.allocatedSizeE ) + { + bbs_ERROR0( "void bim_UInt8PyramidalImage_size( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n" + "Insufficient allocated memory." ); + return; + } +#endif + bbs_UInt8Arr_size( cpA, &ptrA->arrE, sizeL ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8PyramidalImage_memSize( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_SIZEOF16( ptrA->depthE ) + + bbs_UInt8Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8PyramidalImage_memWrite( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bim_UInt8PyramidalImage_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bim_UINT8_PYRAMIDAL_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->depthE, memPtrA ); + bbs_UInt8Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bim_UInt8PyramidalImage_memRead( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL, widthL, heightL, depthL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT8_PYRAMIDAL_IMAGE_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &widthL, memPtrA ); + memPtrA += bbs_memRead32( &heightL, memPtrA ); + memPtrA += bbs_memRead32( &depthL, memPtrA ); + + ptrA->widthE = widthL; + ptrA->heightE = heightL; + ptrA->depthE = depthL; + bbs_UInt8Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bim_UInt8PyramidalImage_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt8PyramidalImage_memRead( const struct bim_UInt8PyramidalImage* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +void bim_UInt8PyramidalImage_overlayUInt8( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + struct bim_UInt8Image* uint8ImageA ) +{ + uint8ImageA->widthE = ptrA->widthE; + uint8ImageA->heightE = ptrA->heightE; + uint8ImageA->arrE.sizeE = ptrA->widthE * ptrA->heightE; + uint8ImageA->arrE.allocatedSizeE = ptrA->widthE * ptrA->heightE; + uint8ImageA->arrE.arrPtrE = ptrA->arrE.arrPtrE; + uint8ImageA->arrE.mspE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_recompute( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* dstPtrA ) +{ + uint32 iL, jL, layerL, widthL, heightL; + uint8 *srcL, *dstL; + + /* process remaining layers */ + widthL = dstPtrA->widthE; + heightL = dstPtrA->heightE; + srcL = dstPtrA->arrE.arrPtrE; + dstL = srcL + widthL * heightL; + for( layerL = 1; layerL < dstPtrA->depthE; layerL++ ) + { + for( jL = ( heightL >> 1 ); jL > 0; jL-- ) + { + for( iL = ( widthL >> 1 ); iL > 0; iL-- ) + { + /* averaging with roundig */ + *dstL++ = ( ( *srcL + *( srcL + 1 ) + *( srcL + widthL ) + *( srcL + widthL + 1 ) ) + 2 ) >> 2; + srcL += 2; + } + srcL += widthL; + } + widthL >>= 1; + heightL >>= 1; + } +} + +/* ------------------------------------------------------------------------- */ + +void bim_UInt8PyramidalImage_importUInt8( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* dstPtrA, + const struct bim_UInt8Image* srcPtrA, + uint32 depthA ) +{ + + bim_UInt8PyramidalImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE, depthA ); + + if( srcPtrA->arrE.sizeE & 1 ) + { + bbs_ERROR0( "void bim_UInt8PyramidalImage_importUInt8(....):\n" + "Size of source image must be even.\n" ); + return; + + } + + /* copy first layer */ + bbs_memcpy16( dstPtrA->arrE.arrPtrE, srcPtrA->arrE.arrPtrE, srcPtrA->arrE.sizeE >> 1 ); + + bim_UInt8PyramidalImage_recompute( cpA, dstPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_ImageEm/UInt8PyramidalImage.h b/Embedded/common/src/b_ImageEm/UInt8PyramidalImage.h new file mode 100644 index 0000000..a4484d3 --- /dev/null +++ b/Embedded/common/src/b_ImageEm/UInt8PyramidalImage.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bim_UINT8_PYRAMIDAL_IMAGE_EM_H +#define bim_UINT8_PYRAMIDAL_IMAGE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_ImageEm/UInt8Image.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +#define bim_PYRAMIDAL_IMAGE_STANDARD_DEPTH 4 + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bim_UINT8_PYRAMIDAL_IMAGE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** Pyramidal image of uint8. + * The Pyramidal format is as follows + * widthE specifies width of first image (image 0) + * heightE specifies height of first image (image 0) + * depthE specifies the number of levels present + * image n has half of the width,heigth dimension of image n-1 + * A pixel of in image n is the average of the corresponding 4 + * covering pixels in image n-1 + * Adresses of data relative to arrE.arrPtrE + * The address of image 0 is 0 + * The address of image 1 is widthE * heightE + * The address of image n is widthE * heightE + widthE * heightE / 4 + ... + widthE * heightE * ( 2^-(2*n) ) + * Use function uint8* bim_UInt8PyramidalImage_arrPtr( uint32 levelA ) to obtain adress of image at given depth level + * Use function bim_UInt8PyramidalImage_importUInt8 to create a pyramidal image from an uint8 image +*/ +struct bim_UInt8PyramidalImage +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** width of image */ + uint32 widthE; + + /** height of image */ + uint32 heightE; + + /** depth of image (number of layers) */ + uint32 depthE; + + /** pyramidal image type (temporary: until switch to 16-bit complete) */ + uint32 typeE; + + /** array of bytes */ + struct bbs_UInt8Arr arrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bim_UInt8PyramidalImage */ +void bim_UInt8PyramidalImage_init( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA ); + +/** allocates memory for bim_UInt8PyramidalImage */ +void bim_UInt8PyramidalImage_create( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + uint32 widthA, uint32 heightA, + uint32 depthA, + struct bbs_MemSeg* mspA ); + +/** frees bim_UInt8PyramidalImage */ +void bim_UInt8PyramidalImage_exit( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bim_UInt8PyramidalImage_copy( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + const struct bim_UInt8PyramidalImage* srcPtrA ); + +/** equal operator */ +flag bim_UInt8PyramidalImage_equal( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, const struct bim_UInt8PyramidalImage* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns adress of image at given depth level */ +uint8* bim_UInt8PyramidalImage_arrPtr( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + uint32 levelA ); + +/** calculates the amount of heap memory needed (16bit words) if created with given parameters */ +uint32 bim_UInt8PyramidalImage_heapSize( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** sets image size */ +void bim_UInt8PyramidalImage_size( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + uint32 widthA, + uint32 heightA, + uint32 depthA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bim_UInt8PyramidalImage_memSize( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bim_UInt8PyramidalImage_memWrite( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bim_UInt8PyramidalImage_memRead( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** create overlay bim_UInt8Image (does not own memory) */ +void bim_UInt8PyramidalImage_overlayUInt8( struct bbs_Context* cpA, + const struct bim_UInt8PyramidalImage* ptrA, + struct bim_UInt8Image* uint8ImageA ); + +/** recompute pyramidal format with given depth from data in layer 0 */ +void bim_UInt8PyramidalImage_recompute( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* dstPtrA ); + +/** import uint8image and creates pyramidal format with given depth */ +void bim_UInt8PyramidalImage_importUInt8( struct bbs_Context* cpA, + struct bim_UInt8PyramidalImage* dstPtrA, + const struct bim_UInt8Image* srcPtrA, + uint32 depthA ); + +#endif /* bim_UINT8_PYRAMIDAL_IMAGE_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Alt.c b/Embedded/common/src/b_TensorEm/Alt.c new file mode 100644 index 0000000..d7373e0 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Alt.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_TensorEm/Alt.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Alt_init( struct bbs_Context* cpA, + struct bts_Alt* ptrA ) +{ + bts_VectorMap_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bts_VM_ALT; + ptrA->baseE.vpMapE = bts_Alt_map; + + bts_CompactAlt_init( cpA, &ptrA->altE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Alt_exit( struct bbs_Context* cpA, + struct bts_Alt* ptrA ) +{ + bts_CompactAlt_exit( cpA, &ptrA->altE ); + + bts_VectorMap_exit( cpA, &ptrA->baseE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Alt_copy( struct bbs_Context* cpA, + struct bts_Alt* ptrA, + const struct bts_Alt* srcPtrA ) +{ + bts_CompactAlt_copy( cpA, &ptrA->altE, &srcPtrA->altE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Alt_equal( struct bbs_Context* cpA, + const struct bts_Alt* ptrA, + const struct bts_Alt* srcPtrA ) +{ + bbs_ERROR0( "bts_Alt_equal:\n Function is not available" ); + return FALSE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Alt_memSize( struct bbs_Context* cpA, + const struct bts_Alt* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + memSizeL += bts_VectorMap_memSize( cpA, &ptrA->baseE ); + memSizeL += bts_CompactAlt_memSize( cpA, &ptrA->altE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Alt_memWrite( struct bbs_Context* cpA, + const struct bts_Alt* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Alt_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_ALT_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bts_CompactAlt_memWrite( cpA, &ptrA->altE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Alt_memRead( struct bbs_Context* cpA, + struct bts_Alt* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_ALT_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bts_CompactAlt_memRead( cpA, &ptrA->altE, memPtrA, espL ); + + if( memSizeL != bts_Alt_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Alt_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Alt_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ) +{ + bbs_DEF_fNameL( "bts_Alt_map" ) + const struct bts_Alt* ptrL = ( const struct bts_Alt* )ptrA; + + if( inVecPtrA->arrE.sizeE != ptrL->altE.matE.widthE ) + { + bbs_ERROR1( "%s:\ninput vector has incorrect size", fNameL ); + return; + } + + if( outVecPtrA->arrE.allocatedSizeE < ptrL->altE.matE.heightE ) + { + bbs_ERROR1( "%s:\noutput vector is insufficiently allocated", fNameL ); + return; + } + + bts_Flt16Vec_size( cpA, outVecPtrA, ptrL->altE.matE.heightE ); + + bts_CompactAlt_map( cpA, &ptrL->altE, inVecPtrA->arrE.arrPtrE, inVecPtrA->expE, outVecPtrA->arrE.arrPtrE, &outVecPtrA->expE ); + + bts_Flt16Vec_maximizeMantisse( cpA, outVecPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Alt.h b/Embedded/common/src/b_TensorEm/Alt.h new file mode 100644 index 0000000..8286834 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Alt.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_ALT_EM_H +#define bts_ALT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/VectorMap.h" +#include "b_TensorEm/CompactAlt.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** data format version number */ +#define bts_ALT_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** applies affine linear transformation to vector */ +struct bts_Alt +{ + /* ---- public data ---------------------------------------------------- */ + + /** base element (must be first element) */ + struct bts_VectorMap baseE; + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /* affine linear transformation */ + struct bts_CompactAlt altE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bts_Alt */ +void bts_Alt_init( struct bbs_Context* cpA, + struct bts_Alt* ptrA ); + +/** resets bts_Alt */ +void bts_Alt_exit( struct bbs_Context* cpA, + struct bts_Alt* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_Alt_copy( struct bbs_Context* cpA, + struct bts_Alt* ptrA, + const struct bts_Alt* srcPtrA ); + +/** equal operator */ +flag bts_Alt_equal( struct bbs_Context* cpA, + const struct bts_Alt* ptrA, + const struct bts_Alt* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bts_Alt_memSize( struct bbs_Context* cpA, + const struct bts_Alt* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_Alt_memWrite( struct bbs_Context* cpA, + const struct bts_Alt* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_Alt_memRead( struct bbs_Context* cpA, + struct bts_Alt* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Vector map operation. + * Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + */ +void bts_Alt_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ); + +#endif /* bts_ALT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Cluster2D.c b/Embedded/common/src/b_TensorEm/Cluster2D.c new file mode 100644 index 0000000..e6acf6e --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Cluster2D.c @@ -0,0 +1,997 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Cluster2D.h" +#include "b_TensorEm/RBFMap2D.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/** Computes relative scale factor from the 2 mean square node distances to the + * cluster centers for 2 clusters. + */ +void bts_Cluster2D_computeScale( uint32 enumA, /* mean square radius, dst cluster */ + int32 bbp_enumA, /* bbp of enumA */ + uint32 denomA, /* mean square radius, src cluster */ + int32 bbp_denomA, /* bbp of denomA */ + uint32* scaleA, /* resulting scale factor */ + int32* bbp_scaleA )/* bbp of scale factor */ +{ + uint32 shiftL, quotientL; + int32 posL, bbp_denomL; + + /* how far can we shift enumA to the left */ + shiftL = 31 - bbs_intLog2( enumA ); + + /* how far do we have to shift denomA to the right */ + posL = bbs_intLog2( denomA ) + 1; + bbp_denomL = bbp_denomA; + + if( posL - bbp_denomL > 12 ) + { + /* if denomA has more than 12 bit before the point, discard bits behind the point */ + denomA >>= bbp_denomL; + bbp_denomL = 0; + } + else + { + /* otherwise reduce denomA to 12 bit */ + bbs_uint32ReduceToNBits( &denomA, &bbp_denomL, 12 ); + } + + /* make result bbp even for call of sqrt */ + if( ( bbp_enumA + shiftL - bbp_denomL ) & 1 ) shiftL--; + + quotientL = ( enumA << shiftL ) / denomA; + + *scaleA = bbs_fastSqrt32( quotientL ); + *bbp_scaleA = ( bbp_enumA + shiftL - bbp_denomL ) >> 1; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_init( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA ) +{ + ptrA->mspE = NULL; + ptrA->vecArrE = NULL; + ptrA->allocatedSizeE = 0; + ptrA->sizeE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_exit( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->vecArrE ); + ptrA->vecArrE = NULL; + ptrA->mspE = NULL; + ptrA->allocatedSizeE = 0; + ptrA->sizeE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_copy( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const struct bts_Cluster2D* srcPtrA ) +{ +#ifdef DEBUG2 + if( ptrA->allocatedSizeE < srcPtrA->sizeE ) + { + bbs_ERROR0( "void bts_Cluster2D_copy( struct bts_Cluster2D* ptrA, const struct bts_Cluster2D* srcPtrA ): allocated size too low in destination cluster" ); + return; + } +#endif + + bbs_memcpy32( ptrA->vecArrE, srcPtrA->vecArrE, bbs_SIZEOF32( struct bts_Int16Vec2D ) * srcPtrA->sizeE ); + + ptrA->bbpE = srcPtrA->bbpE; + ptrA->sizeE = srcPtrA->sizeE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Cluster2D_equal( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + const struct bts_Cluster2D* srcPtrA ) +{ + uint32 iL; + const struct bts_Int16Vec2D* src1L = ptrA->vecArrE; + const struct bts_Int16Vec2D* src2L = srcPtrA->vecArrE; + + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + if( ptrA->bbpE != srcPtrA->bbpE ) return FALSE; + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( ( src1L->xE != src2L->xE ) || ( src1L->yE != src2L->yE ) ) return FALSE; + src1L++; + src2L++; + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Cluster2D_center( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ) +{ + struct bts_Int16Vec2D* vecPtrL = ptrA->vecArrE; + uint32 iL; + int32 xL = 0; + int32 yL = 0; + + if( ptrA->sizeE == 0 ) return bts_Flt16Vec2D_create16( 0, 0, 0 ); + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + xL += vecPtrL->xE; + yL += vecPtrL->yE; + vecPtrL++; + } + + xL = ( ( ( xL << 1 ) / ( int32 )ptrA->sizeE ) + 1 ) >> 1; + yL = ( ( ( yL << 1 ) / ( int32 )ptrA->sizeE ) + 1 ) >> 1; + + return bts_Flt16Vec2D_create16( ( int16 )xL, ( int16 )yL, ( int16 )ptrA->bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster2D_checkSum( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ) +{ + struct bts_Int16Vec2D* vecPtrL = ptrA->vecArrE; + uint32 iL; + int32 sumL = ptrA->bbpE; + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + sumL += vecPtrL->xE; + sumL += vecPtrL->yE; + vecPtrL++; + } + + return (uint32)sumL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Rect bts_Cluster2D_boundingBox( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ) +{ + struct bts_Int16Vec2D* vecPtrL = ptrA->vecArrE; + uint32 iL; + int32 xMinL = 65536; + int32 yMinL = 65536; + int32 xMaxL = -65536; + int32 yMaxL = -65536; + + if( ptrA->sizeE == 0 ) return bts_Int16Rect_create( 0, 0, 0, 0 ); + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + xMinL = bbs_min( xMinL, vecPtrL->xE ); + yMinL = bbs_min( yMinL, vecPtrL->yE ); + xMaxL = bbs_max( xMaxL, vecPtrL->xE ); + yMaxL = bbs_max( yMaxL, vecPtrL->yE ); + vecPtrL++; + } + + return bts_Int16Rect_create( ( int16 )xMinL, ( int16 )yMinL, ( int16 )xMaxL, ( int16 )yMaxL ); +} + + +/* ------------------------------------------------------------------------- */ + +int32 bts_Cluster2D_int32X( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + uint32 indexA, int32 bbpA ) +{ +#ifdef DEBUG2 + if( indexA >= ptrA->sizeE ) + { + bbs_ERROR2( "int32 bts_Cluster2D_int32X( .... )\n" + "indexA = %i is out of range [0,%i]", + indexA, + ptrA->sizeE - 1 ); + return 0; + } +#endif + + { + int32 shiftL = bbpA - ptrA->bbpE; + int32 xL = ptrA->vecArrE[ indexA ].xE; + if( shiftL >= 0 ) + { + xL <<= shiftL; + } + else + { + xL = ( ( xL >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } + + return xL; + } +} + +/* ------------------------------------------------------------------------- */ + +int32 bts_Cluster2D_int32Y( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + uint32 indexA, + int32 bbpA ) +{ +#ifdef DEBUG2 + if( indexA >= ptrA->sizeE ) + { + bbs_ERROR2( "int32 bts_Cluster2D_int32Y( .... )\n" + "indexA = %i is out of range [0,%i]", + indexA, + ptrA->sizeE - 1 ); + return 0; + } +#endif + { + int32 shiftL = bbpA - ptrA->bbpE; + int32 yL = ptrA->vecArrE[ indexA ].yE; + if( shiftL >= 0 ) + { + yL <<= shiftL; + } + else + { + yL = ( ( yL >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } + + return yL; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_create( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->mspE == NULL ) + { + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->vecArrE = NULL; + } + + if( ptrA->sizeE == sizeA ) return; + + if( ptrA->vecArrE != 0 ) + { + bbs_ERROR0( "void bts_Cluster2D_create( const struct bts_Cluster2D*, uint32 ):\n" + "object has already been created and cannot be resized." ); + return; + } + + ptrA->vecArrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( struct bts_Int16Vec2D ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->sizeE = sizeA; + ptrA->allocatedSizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_size( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR2( "void bts_Cluster2D_size( struct bts_Cluster2D* ptrA, uint32 sizeA ):\n" + "Allocated size (%i) of cluster is smaller than requested size (%i).", + ptrA->allocatedSizeE, + sizeA ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_transform( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + struct bts_Flt16Alt2D altA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + struct bts_Flt16Vec2D vL = bts_Flt16Vec2D_createVec16( ptrA->vecArrE[ iL ], ptrA->bbpE ); + ptrA->vecArrE[ iL ] = bts_Flt16Vec2D_int16Vec2D( bts_Flt16Alt2D_mapFlt( &altA, &vL ), ptrA->bbpE ); + } +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_transformBbp( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + struct bts_Flt16Alt2D altA, + uint32 dstBbpA ) +{ + uint32 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + struct bts_Flt16Vec2D vL = bts_Flt16Vec2D_createVec16( ptrA->vecArrE[ iL ], ptrA->bbpE ); + ptrA->vecArrE[ iL ] = bts_Flt16Vec2D_int16Vec2D( bts_Flt16Alt2D_mapFlt( &altA, &vL ), dstBbpA ); + } + ptrA->bbpE = dstBbpA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_rbfTransform( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const struct bts_RBFMap2D* rbfMapPtrA ) +{ + bts_RBFMap2D_mapCluster( cpA, rbfMapPtrA, ptrA, ptrA, ptrA->bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster2D_copyTransform( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const struct bts_Cluster2D* srcPtrA, + struct bts_Flt16Alt2D altA, + uint32 dstBbpA ) +{ + uint32 iL; + + /* prepare destination cluster */ + if( ptrA->allocatedSizeE < srcPtrA->sizeE ) + { + bbs_ERROR0( "void bts_Cluster2D_copyTransform( struct bts_Cluster2D* ptrA, const struct bts_Cluster2D* srcPtrA, struct bts_Flt16Alt2D altA, uint32 dstBbpA ): allocated size too low in destination cluster" ); + return; + } + + ptrA->sizeE = srcPtrA->sizeE; + ptrA->bbpE = dstBbpA; + + /* transform */ + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + struct bts_Flt16Vec2D vL = bts_Flt16Vec2D_createVec16( srcPtrA->vecArrE[ iL ], srcPtrA->bbpE ); + ptrA->vecArrE[ iL ] = bts_Flt16Vec2D_int16Vec2D( bts_Flt16Alt2D_mapFlt( &altA, &vL ), ptrA->bbpE ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster2D_memSize( struct bbs_Context* cpA, + const struct bts_Cluster2D *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) /* mem size */ + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->sizeE ) + + bbs_SIZEOF16( ptrA->bbpE ) + + bbs_SIZEOF16( struct bts_Int16Vec2D ) * ptrA->sizeE; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster2D_memWrite( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Cluster2D_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_CLUSTER2D_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->bbpE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->vecArrE, ptrA->sizeE * 2, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster2D_memRead( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL; + uint32 sizeL; + uint32 versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_CLUSTER2D_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->bbpE, memPtrA ); + + if( ptrA->allocatedSizeE < sizeL ) + { + bts_Cluster2D_create( cpA, ptrA, sizeL, mspA ); + } + else + { + bts_Cluster2D_size( cpA, ptrA, sizeL ); + } + + memPtrA += bbs_memRead16Arr( cpA, ptrA->vecArrE, ptrA->sizeE * 2, memPtrA ); + + if( memSizeL != bts_Cluster2D_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Cluster2D_memRead( const struct bts_Cluster2D* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Cluster2D_alt( struct bbs_Context* cpA, + const struct bts_Cluster2D* srcPtrA, + const struct bts_Cluster2D* dstPtrA, + enum bts_AltType altTypeA ) +{ + struct bts_Flt16Alt2D altL = bts_Flt16Alt2D_createIdentity(); + enum bts_AltType altTypeL = altTypeA; + + uint32 sizeL = srcPtrA->sizeE; + int32 srcBbpL = srcPtrA->bbpE; + int32 dstBbpL = dstPtrA->bbpE; + + struct bts_Flt16Vec2D cpL, cqL, cpMappedL, cpAdjustedL; + + if( dstPtrA->sizeE != srcPtrA->sizeE ) + { + bbs_ERROR2( "struct bts_Flt16Alt2D bts_Cluster2D_alt( ... ):\n" + "the 2 input clusters differ in size: %d vs %d", srcPtrA->sizeE, dstPtrA->sizeE ); + } + + if( sizeL <= 2 ) + { + if( altTypeL == bts_ALT_LINEAR ) + { + altTypeL = bts_ALT_RIGID; + } + } + + if( sizeL <= 1 ) + { + if( altTypeL == bts_ALT_RIGID ) + { + altTypeL = bts_ALT_TRANS; + } + else if( altTypeL == bts_ALT_TRANS_SCALE ) + { + altTypeL = bts_ALT_TRANS; + } + } + + if( sizeL == 0 || altTypeL == bts_ALT_IDENTITY ) + { + /* return identity */ + return altL; + } + + cpL = bts_Cluster2D_center( cpA, srcPtrA ); + cqL = bts_Cluster2D_center( cpA, dstPtrA ); + + if( altTypeL == bts_ALT_TRANS ) + { + /* return translation only */ + altL.vecE = bts_Flt16Vec2D_sub( cqL, cpL ); + return altL; + } + + switch( altTypeL ) + { + case bts_ALT_TRANS_SCALE: + { + uint32 spL = 0; + uint32 sqL = 0; + + struct bts_Int16Vec2D* srcPtrL = srcPtrA->vecArrE; + struct bts_Int16Vec2D* dstPtrL = dstPtrA->vecArrE; + + int32 iL = sizeL; + while( iL-- ) + { + int32 pxL = srcPtrL->xE - cpL.xE; + int32 pyL = srcPtrL->yE - cpL.yE; + int32 qxL = dstPtrL->xE - cqL.xE; + int32 qyL = dstPtrL->yE - cqL.yE; + srcPtrL++; + dstPtrL++; + + /* overflow estimate: no problem with 100 nodes, bbp = 6, x = y = 500 */ + spL += ( pxL * pxL ) >> srcBbpL; + spL += ( pyL * pyL ) >> srcBbpL; + sqL += ( qxL * qxL ) >> dstBbpL; + sqL += ( qyL * qyL ) >> dstBbpL; + } + + spL /= sizeL; + sqL /= sizeL; + + if( spL == 0 ) + { + bbs_ERROR0( "struct bts_Flt16Alt2D bts_Cluster2D_alt( ... ):\n" + "All nodes of the src cluster are sitting in the center -> " + "unable to compute scale matrix between clusters" ); + } + else + { + uint32 scaleL; + int32 factor32L, bbp_scaleL; + int16 factor16L; + + bts_Cluster2D_computeScale( sqL, dstBbpL, spL, srcBbpL, &scaleL, &bbp_scaleL ); + + /* create scale matrix */ + factor32L = ( int32 )scaleL; + altL.matE = bts_Flt16Mat2D_createScale( factor32L, bbp_scaleL ); + + /* create translation vector */ + factor16L = scaleL; + cpMappedL = bts_Flt16Vec2D_mul( cpL, factor16L, bbp_scaleL ); + altL.vecE = bts_Flt16Vec2D_sub( cqL, cpMappedL ); + + return altL; + } + } + break; + + case bts_ALT_RIGID: + { + /* smaller of the 2 bbp's */ + int32 minBbpL = bbs_min( srcBbpL, dstBbpL ); + + uint32 spL = 0; + uint32 sqL = 0; + int32 pxqxL = 0; + int32 pxqyL = 0; + int32 pyqxL = 0; + int32 pyqyL = 0; + + struct bts_Int16Vec2D* srcPtrL = srcPtrA->vecArrE; + struct bts_Int16Vec2D* dstPtrL = dstPtrA->vecArrE; + + int32 iL = sizeL; + while( iL-- ) + { + int32 pxL = srcPtrL->xE - cpL.xE; + int32 pyL = srcPtrL->yE - cpL.yE; + int32 qxL = dstPtrL->xE - cqL.xE; + int32 qyL = dstPtrL->yE - cqL.yE; + srcPtrL++; + dstPtrL++; + + /* overflow estimate: no problem with 100 nodes, bbp = 6, x = y = 500 */ + spL += ( pxL * pxL ) >> srcBbpL; + spL += ( pyL * pyL ) >> srcBbpL; + sqL += ( qxL * qxL ) >> dstBbpL; + sqL += ( qyL * qyL ) >> dstBbpL; + + pxqxL += ( pxL * qxL ) >> minBbpL; + pxqyL += ( pxL * qyL ) >> minBbpL; + pyqxL += ( pyL * qxL ) >> minBbpL; + pyqyL += ( pyL * qyL ) >> minBbpL; + } + + spL /= sizeL; + sqL /= sizeL; + pxqxL /= ( int32 )sizeL; + pxqyL /= ( int32 )sizeL; + pyqxL /= ( int32 )sizeL; + pyqyL /= ( int32 )sizeL; + + if( spL == 0 ) + { + bbs_ERROR0( "struct bts_Flt16Alt2D bts_Cluster2D_alt( ... ):\n" + "All nodes of the src cluster are sitting in the center -> " + "unable to compute scale matrix between clusters" ); + } + else + { + uint32 scaleL, shiftL, quotientL, enumL, denomL, bitsTaken0L, bitsTaken1L; + int32 bbp_scaleL, cL, rL, c1L, r1L; + int32 ppL, pmL, mpL, mmL, maxL; + int32 quotientBbpL, bbp_crL, posL; + + + /* find scale factor: */ + + bts_Cluster2D_computeScale( sqL, dstBbpL, spL, srcBbpL, &scaleL, &bbp_scaleL ); + + + /* find rotation matrix: */ + + /* sign not needed any more */ + enumL = bbs_abs( pxqyL - pyqxL ); + denomL = bbs_abs( pxqxL + pyqyL ); + + if( denomL == 0 ) + { + cL = 0; + rL = 1; + quotientBbpL = 0; + } + else + { + /* original formula: + + float aL = enumL / denomL; + cL = sqrt( 1.0 / ( 1.0 + ebs_sqr( aL ) ) ); + rL = sqrt( 1 - ebs_sqr( cL ) ); + + */ + + /* how far can we shift enumL to the left */ + shiftL = 31 - bbs_intLog2( enumL ); + + /* result has bbp = shiftL */ + quotientL = ( enumL << shiftL ) / denomL; + quotientBbpL = shiftL; + + posL = bbs_intLog2( quotientL ); + + /* if enumL much larger than denomL, then we cannot square the quotient */ + if( posL > ( quotientBbpL + 14 ) ) + { + cL = 0; + rL = 1; + quotientBbpL = 0; + } + else if( quotientBbpL > ( posL + 14 ) ) + { + cL = 1; + rL = 0; + quotientBbpL = 0; + } + else + { + bbs_uint32ReduceToNBits( "ientL, "ientBbpL, 15 ); + + /* to avoid an overflow in the next operation */ + if( quotientBbpL > 15 ) + { + quotientL >>= ( quotientBbpL - 15 ); + quotientBbpL -= ( quotientBbpL - 15 ); + } + + /* result has again bbp = quotientBbpL */ + denomL = bbs_fastSqrt32( quotientL * quotientL + ( ( int32 )1 << ( quotientBbpL << 1 ) ) ); + + quotientL = ( ( uint32 )1 << 31 ) / denomL; + quotientBbpL = 31 - quotientBbpL; + + bbs_uint32ReduceToNBits( "ientL, "ientBbpL, 15 ); + + /* to avoid an overflow in the next operation */ + if( quotientBbpL > 15 ) + { + quotientL >>= ( quotientBbpL - 15 ); + quotientBbpL -= ( quotientBbpL - 15 ); + } + + cL = quotientL; + rL = bbs_fastSqrt32( ( ( int32 )1 << ( quotientBbpL << 1 ) ) - quotientL * quotientL ); + } + } + + /* save cL and rL with this accuracy for later */ + c1L = cL; + r1L = rL; + bbp_crL = quotientBbpL; + + /* prepare the next computations */ + bitsTaken0L = bts_maxAbsIntLog2Of4( pxqxL, pxqyL, pyqxL, pyqyL ) + 1; + bitsTaken1L = bts_maxAbsIntLog2Of2( cL, rL ) + 1; + + if( ( bitsTaken0L + bitsTaken1L ) > 29 ) + { + int32 shiftL = bitsTaken0L + bitsTaken1L - 29; + cL >>= shiftL; + rL >>= shiftL; + quotientBbpL -= shiftL; + } + + /* best combination: */ + ppL = cL * pxqxL - rL * pyqxL + cL * pyqyL + rL * pxqyL; + pmL = cL * pxqxL + rL * pyqxL + cL * pyqyL - rL * pxqyL; + mpL = - cL * pxqxL - rL * pyqxL - cL * pyqyL + rL * pxqyL; + mmL = - cL * pxqxL + rL * pyqxL - cL * pyqyL - rL * pxqyL; + + maxL = bbs_max( bbs_max( ppL, pmL ), bbs_max( mpL, mmL ) ); + + /* restore cL and rL, bbp = bbp_crL */ + cL = c1L; + rL = r1L; + + /* rotation matrix */ + if( ppL == maxL ) + { + altL.matE = bts_Flt16Mat2D_create32( cL, -rL, rL, cL, bbp_crL ); + } + else if( pmL == maxL ) + { + altL.matE = bts_Flt16Mat2D_create32( cL, rL, -rL, cL, bbp_crL ); + } + else if( mpL == maxL ) + { + altL.matE = bts_Flt16Mat2D_create32( -cL, -rL, rL, -cL, bbp_crL ); + } + else + { + altL.matE = bts_Flt16Mat2D_create32( -cL, rL, -rL, -cL, bbp_crL ); + } + + + /* find translation: */ + + /* original formula: + + ets_Float2DVec transL = cqL - ( scaleL * ( rotL * cpL ) ); + altL.mat( rotL * scaleL ); + altL.vec( transL ); + + */ + + bts_Flt16Mat2D_scale( &altL.matE, scaleL, bbp_scaleL ); + cpMappedL = bts_Flt16Mat2D_mapFlt( &altL.matE, &cpL ); + altL.vecE = bts_Flt16Vec2D_sub( cqL, cpMappedL ); + } + + return altL; + } + + case bts_ALT_LINEAR: + { + /* smaller of the 2 bbp's */ + int32 minBbpL = bbs_min( srcBbpL, dstBbpL ); + + int32 iL = 0; + int32 pxpxL = 0; + int32 pxpyL = 0; + int32 pypyL = 0; + int32 pxqxL = 0; + int32 pxqyL = 0; + int32 pyqxL = 0; + int32 pyqyL = 0; + + struct bts_Int16Vec2D* srcPtrL = srcPtrA->vecArrE; + struct bts_Int16Vec2D* dstPtrL = dstPtrA->vecArrE; + + /* get cp adjusted to dstBbpL */ + int32 shiftL = dstBbpL - srcBbpL; + if( shiftL > 0 ) + { + cpAdjustedL.xE = cpL.xE << shiftL; + cpAdjustedL.yE = cpL.yE << shiftL; + cpAdjustedL.bbpE = dstBbpL; + } + else + { + cpAdjustedL.xE = ( ( cpL.xE >> ( -shiftL - 1 ) ) + 1 ) >> 1; + cpAdjustedL.yE = ( ( cpL.yE >> ( -shiftL - 1 ) ) + 1 ) >> 1; + cpAdjustedL.bbpE = dstBbpL; + } + + iL = sizeL; + while( iL-- ) + { + int32 pxL = srcPtrL->xE - cpL.xE; + int32 pyL = srcPtrL->yE - cpL.yE; + int32 qxL = dstPtrL->xE - cpAdjustedL.xE; /* cp, not cq! */ + int32 qyL = dstPtrL->yE - cpAdjustedL.yE; + srcPtrL++; + dstPtrL++; + + /* overflow estimate: no problem with 100 nodes, bbp = 6, x = y = 500 */ + pxpxL += ( pxL * pxL ) >> srcBbpL; + pxpyL += ( pxL * pyL ) >> srcBbpL; + pypyL += ( pyL * pyL ) >> srcBbpL; + + pxqxL += ( pxL * qxL ) >> minBbpL; + pxqyL += ( pxL * qyL ) >> minBbpL; + pyqxL += ( pyL * qxL ) >> minBbpL; + pyqyL += ( pyL * qyL ) >> minBbpL; + } + + pxpxL /= ( int32 )sizeL; + pxpyL /= ( int32 )sizeL; + pypyL /= ( int32 )sizeL; + pxqxL /= ( int32 )sizeL; + pxqyL /= ( int32 )sizeL; + pyqxL /= ( int32 )sizeL; + pyqyL /= ( int32 )sizeL; + + { + /* original code: + + float detPL = ( pxpxL * pypyL ) - ( pxpyL * pxpyL ); + + if( ebs_neglectable( detPL ) ) + { + matL.setIdentity(); + } + else + { + matL.xx( ( pxqxL * pypyL - pyqxL * pxpyL ) / detPL ); + matL.xy( ( pyqxL * pxpxL - pxqxL * pxpyL ) / detPL ); + matL.yx( ( pxqyL * pypyL - pyqyL * pxpyL ) / detPL ); + matL.yy( ( pyqyL * pxpxL - pxqyL * pxpyL ) / detPL ); + } + + */ + + /* compute det first */ + uint32 bitsTaken0L = bts_maxAbsIntLog2Of4( pxpxL, pypyL, pxpyL, pxpyL ) + 1; + int32 shL = 0; + int32 detL = 0; + int32 detBbpL = 0; + + if( bitsTaken0L > 15 ) + { + shL = bitsTaken0L - 15; + } + + detL = ( pxpxL >> shL ) * ( pypyL >> shL ) - ( pxpyL >> shL ) * ( pxpyL >> shL ); + + /* this can be negative */ + detBbpL = ( srcBbpL - shL ) << 1; + + /* reduce to 15 bit */ + shL = ( int32 )bts_absIntLog2( detL ); + if( shL > 15 ) + { + detL >>= ( shL - 15 ); + detBbpL -= ( shL - 15 ); + } + + if( detL != 0 ) + { + int32 sh0L, sh1L, xxL, xyL, yxL, yyL, bbp_enumL; + uint32 bitsTaken1L, highestBitL; + + sh0L = 0; + if( bitsTaken0L > 15 ) + { + sh0L = bitsTaken0L - 15; + } + + bitsTaken1L = bts_maxAbsIntLog2Of4( pxqxL, pxqyL, pyqxL, pyqyL ) + 1; + sh1L = 0; + if( bitsTaken1L > 15 ) + { + sh1L = bitsTaken1L - 15; + } + + xxL = ( pxqxL >> sh1L ) * ( pypyL >> sh0L ) - ( pyqxL >> sh1L ) * ( pxpyL >> sh0L ); + xyL = ( pyqxL >> sh1L ) * ( pxpxL >> sh0L ) - ( pxqxL >> sh1L ) * ( pxpyL >> sh0L ); + yxL = ( pxqyL >> sh1L ) * ( pypyL >> sh0L ) - ( pyqyL >> sh1L ) * ( pxpyL >> sh0L ); + yyL = ( pyqyL >> sh1L ) * ( pxpxL >> sh0L ) - ( pxqyL >> sh1L ) * ( pxpyL >> sh0L ); + + /* again, can be negative */ + bbp_enumL = ( srcBbpL - sh0L ) + ( bbs_max( srcBbpL, dstBbpL ) - sh1L ); + + highestBitL = bts_maxAbsIntLog2Of4( xxL, xyL, yxL, yyL ) + 1; + + /* shift left */ + xxL <<= ( 31 - highestBitL ); + xyL <<= ( 31 - highestBitL ); + yxL <<= ( 31 - highestBitL ); + yyL <<= ( 31 - highestBitL ); + + bbp_enumL += ( 31 - highestBitL ); + + xxL /= detL; + xyL /= detL; + yxL /= detL; + yyL /= detL; + + bbp_enumL -= detBbpL; + + altL.matE = bts_Flt16Mat2D_create32( xxL, xyL, yxL, yyL, bbp_enumL ); + } + + cpMappedL = bts_Flt16Mat2D_mapFlt( &altL.matE, &cpL ); + altL.vecE = bts_Flt16Vec2D_sub( cqL, cpMappedL ); + } + + return altL; + } + + default: + { + bbs_ERROR1( "struct bts_Flt16Alt2D bts_Cluster2D_alt( ... ):\n" + "altType %d is not handled", altTypeL ); + } + } + + return altL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Cluster2D.h b/Embedded/common/src/b_TensorEm/Cluster2D.h new file mode 100644 index 0000000..43ae987 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Cluster2D.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_CLUSTER2D_EM_H +#define bts_CLUSTER2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" +#include "b_TensorEm/Int16Vec2D.h" +#include "b_TensorEm/Flt16Vec2D.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt2D.h" +#include "b_TensorEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +struct bts_RBFMap2D; + +/* ---- typedefs ----------------------------------------------------------- */ + +/* data format version number */ +#define bts_CLUSTER2D_VERSION 100 + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d vector array */ +struct bts_Cluster2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /** number of allocated vectors */ + uint32 allocatedSizeE; + + /** number of vectors */ + uint32 sizeE; + + /** format of vectors (bbpE always > 0) */ + int32 bbpE; + + /** array of int16 vectors */ + struct bts_Int16Vec2D* vecArrE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes cluster */ +void bts_Cluster2D_init( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA ); + +/** destroys cluster */ +void bts_Cluster2D_exit( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copies cluster */ +void bts_Cluster2D_copy( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const struct bts_Cluster2D* srcPtrA ); + +/** compares cluster */ +flag bts_Cluster2D_equal( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + const struct bts_Cluster2D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns center of gravity */ +struct bts_Flt16Vec2D bts_Cluster2D_center( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ); + +/** returns check sum (for debugging purpose) */ +uint32 bts_Cluster2D_checkSum( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ); + +/** returns bounding box */ +struct bts_Int16Rect bts_Cluster2D_boundingBox( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ); + +/** returns int32 x-coordinate with given bbp at indexed position */ +int32 bts_Cluster2D_int32X( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + uint32 indexA, int32 bbpA ); + +/** returns int32 y-coordinate with given bbp at indexed position */ +int32 bts_Cluster2D_int32Y( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + uint32 indexA, + int32 bbpA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates cluster */ +void bts_Cluster2D_create( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** resize cluster (sizeA must be smaller or equal to allocated size)*/ +void bts_Cluster2D_size( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + uint32 sizeA ); + +/** transforms cluster according to alt (function does not change bbp of cluster) */ +void bts_Cluster2D_transform( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + struct bts_Flt16Alt2D altA ); + +/** transforms cluster according to alt and set bbp of output cluster */ +void bts_Cluster2D_transformBbp( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + struct bts_Flt16Alt2D altA, + uint32 dstBbpA ); + +/** transforms cluster with rbf map (function does not change bbp of cluster) */ +void bts_Cluster2D_rbfTransform( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const struct bts_RBFMap2D* rbfMapPtrA ); + +/** copies src cluster and simultaneously transforms vectors according to alt using dstBbpA as resulting cluster format */ +void bts_Cluster2D_copyTransform( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const struct bts_Cluster2D* srcPtrA, + struct bts_Flt16Alt2D altA, + uint32 dstBbpA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size in words (16-bit) object needs when written to memory */ +uint32 bts_Cluster2D_memSize( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_Cluster2D_memWrite( struct bbs_Context* cpA, + const struct bts_Cluster2D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_Cluster2D_memRead( struct bbs_Context* cpA, + struct bts_Cluster2D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Computes the best affine linear transformation from *srcPtrA to *dstPtrA. + * Constrains of trafo are given by altTypeA + */ +struct bts_Flt16Alt2D bts_Cluster2D_alt( struct bbs_Context* cpA, + const struct bts_Cluster2D* srcPtrA, + const struct bts_Cluster2D* dstPtrA, + enum bts_AltType altTypeA ); + +#endif /* bts_CLUSTER2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Cluster3D.c b/Embedded/common/src/b_TensorEm/Cluster3D.c new file mode 100644 index 0000000..cb6dbd9 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Cluster3D.c @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Cluster3D.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster3D_init( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA ) +{ + ptrA->mspE = NULL; + ptrA->vecArrE = NULL; + ptrA->allocatedSizeE = 0; + ptrA->sizeE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster3D_exit( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA ) +{ + bbs_MemSeg_free( cpA, ptrA->mspE, ptrA->vecArrE ); + ptrA->vecArrE = NULL; + ptrA->mspE = NULL; + ptrA->allocatedSizeE = 0; + ptrA->sizeE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster3D_copy( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + const struct bts_Cluster3D* srcPtrA ) +{ +#ifdef DEBUG1 + if( ptrA->allocatedSizeE < srcPtrA->sizeE ) + { + bbs_ERROR0( "void bts_Cluster3D_copy( struct bts_Cluster2D* ptrA, const struct bts_Cluster2D* srcPtrA ): allocated size too low in destination cluster" ); + return; + } +#endif + + bbs_memcpy16( ptrA->vecArrE, srcPtrA->vecArrE, bbs_SIZEOF16( struct bts_Int16Vec3D ) * srcPtrA->sizeE ); + + ptrA->bbpE = srcPtrA->bbpE; + ptrA->sizeE = srcPtrA->sizeE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Cluster3D_equal( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + const struct bts_Cluster3D* srcPtrA ) +{ + uint32 iL; + const struct bts_Int16Vec3D* src1L = ptrA->vecArrE; + const struct bts_Int16Vec3D* src2L = srcPtrA->vecArrE; + + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + if( ptrA->bbpE != srcPtrA->bbpE ) return FALSE; + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + if( ( src1L->xE != src2L->xE ) || + ( src1L->yE != src2L->yE ) || + ( src1L->zE != src2L->zE ) ) return FALSE; + src1L++; + src2L++; + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Cluster3D_center( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA ) +{ + struct bts_Int16Vec3D* vecPtrL = ptrA->vecArrE; + uint32 iL; + int32 xL = 0; + int32 yL = 0; + int32 zL = 0; + + if( ptrA->sizeE == 0 ) return bts_Flt16Vec3D_create16( 0, 0, 0, 0 ); + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + xL += vecPtrL->xE; + yL += vecPtrL->yE; + zL += vecPtrL->zE; + vecPtrL++; + } + + xL = ( ( ( xL << 1 ) / ( int32 )ptrA->sizeE ) + 1 ) >> 1; + yL = ( ( ( yL << 1 ) / ( int32 )ptrA->sizeE ) + 1 ) >> 1; + zL = ( ( ( zL << 1 ) / ( int32 )ptrA->sizeE ) + 1 ) >> 1; + + return bts_Flt16Vec3D_create16( ( int16 )xL, ( int16 )yL, ( int16 )zL, ( int16 )ptrA->bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Rect bts_Cluster3D_boundingBox( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA ) +{ + struct bts_Int16Vec3D* vecPtrL = ptrA->vecArrE; + uint32 iL; + int32 xMinL = 65536; /*( 1 << 16 )*/ + int32 yMinL = 65536; /*( 1 << 16 )*/ + int32 xMaxL = 0; + int32 yMaxL = 0; + + if( ptrA->sizeE == 0 ) return bts_Int16Rect_create( 0, 0, 0, 0 ); + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + xMinL = bbs_min( xMinL, vecPtrL->xE ); + yMinL = bbs_min( yMinL, vecPtrL->yE ); + xMaxL = bbs_max( xMaxL, vecPtrL->xE ); + yMaxL = bbs_max( yMaxL, vecPtrL->yE ); + vecPtrL++; + } + + return bts_Int16Rect_create( ( int16 )xMinL, ( int16 )yMinL, ( int16 )xMaxL, ( int16 )yMaxL ); +} + +/* ------------------------------------------------------------------------- */ + +int32 bts_Cluster3D_int32X( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint32 indexA, int32 bbpA ) +{ + int32 shiftL = bbpA - ptrA->bbpE; +#ifdef DEBUG2 + if( indexA >= ptrA->sizeE ) + { + bbs_ERROR2( "int32 bts_Cluster2D_int32X( .... )\n" + "indexA = %i is out of range [0,%i]", + indexA, + ptrA->sizeE - 1 ); + return 0; + } +#endif + if( shiftL >= 0 ) + { + return ( int32 ) ptrA->vecArrE[ indexA ].xE << shiftL; + } + else + { + return ( ( ( int32 ) ptrA->vecArrE[ indexA ].xE >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } +} + +/* ------------------------------------------------------------------------- */ + +int32 bts_Cluster3D_int32Y( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint32 indexA, + int32 bbpA ) +{ + int32 shiftL = bbpA - ptrA->bbpE; +#ifdef DEBUG2 + if( indexA >= ptrA->sizeE ) + { + bbs_ERROR2( "int32 bts_Cluster2D_int32Y( .... )\n" + "indexA = %i is out of range [0,%i]", + indexA, + ptrA->sizeE - 1 ); + return 0; + } +#endif + if( shiftL >= 0 ) + { + return ( int32 ) ptrA->vecArrE[ indexA ].yE << shiftL; + } + else + { + return ( ( ( int32 ) ptrA->vecArrE[ indexA ].yE >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } +} + +/* ------------------------------------------------------------------------- */ + +int32 bts_Cluster3D_int32Z( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint32 indexA, + int32 bbpA ) +{ + int32 shiftL = bbpA - ptrA->bbpE; +#ifdef DEBUG2 + if( indexA >= ptrA->sizeE ) + { + bbs_ERROR2( "int32 bts_Cluster2D_int32Z( .... )\n" + "indexA = %i is out of range [0,%i]", + indexA, + ptrA->sizeE - 1 ); + return 0; + } +#endif + if( shiftL >= 0 ) + { + return ( int32 ) ptrA->vecArrE[ indexA ].zE << shiftL; + } + else + { + return ( ( ( int32 ) ptrA->vecArrE[ indexA ].zE >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster3D_create( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( ptrA->mspE == NULL ) + { + ptrA->sizeE = 0; + ptrA->allocatedSizeE = 0; + ptrA->vecArrE = NULL; + } + + if( ptrA->sizeE == sizeA ) return; + + if( ptrA->vecArrE != 0 ) + { + bbs_ERROR0( "void bts_Cluster3D_create( const struct bts_Cluster3D*, uint32 ):\n" + "object has already been created and cannot be resized." ); + return; + } + + ptrA->vecArrE = bbs_MemSeg_alloc( cpA, mspA, sizeA * bbs_SIZEOF16( struct bts_Int16Vec3D ) ); + if( bbs_Context_error( cpA ) ) return; + ptrA->sizeE = sizeA; + ptrA->allocatedSizeE = sizeA; + if( !mspA->sharedE ) ptrA->mspE = mspA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster3D_size( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + uint32 sizeA ) +{ + if( ptrA->allocatedSizeE < sizeA ) + { + bbs_ERROR2( "void bts_Cluster3D_size( struct bts_Cluster3D* ptrA, uint32 sizeA ):\n" + "Allocated size (%i) of cluster is smaller than requested size (%i).", + ptrA->allocatedSizeE, + sizeA ); + return; + } + ptrA->sizeE = sizeA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Cluster3D_transform( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + struct bts_Flt16Alt3D altA ) +{ + struct bts_Int16Vec3D* vecPtrL = ptrA->vecArrE; + uint32 iL; + + int32 x0L = altA.vecE.xE; + int32 y0L = altA.vecE.yE; + int32 z0L = altA.vecE.zE; + + int32 shiftL = altA.matE.bbpE + ptrA->bbpE - altA.vecE.bbpE; + + if( shiftL < 0 ) + { + x0L = ( ( x0L >> ( -shiftL - 1 ) ) + 1 ) >> 1; + y0L = ( ( y0L >> ( -shiftL - 1 ) ) + 1 ) >> 1; + z0L = ( ( z0L >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } + else + { + x0L <<= shiftL; + y0L <<= shiftL; + z0L <<= shiftL; + } + + if( altA.matE.bbpE > 0 ) + { + x0L += (int32)1 << ( altA.matE.bbpE - 1 ); + y0L += (int32)1 << ( altA.matE.bbpE - 1 ); + z0L += (int32)1 << ( altA.matE.bbpE - 1 ); + } + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + int32 xL = vecPtrL->xE; + int32 yL = vecPtrL->yE; + int32 zL = vecPtrL->zE; + vecPtrL->xE = ( x0L + xL * altA.matE.xxE + yL * altA.matE.xyE + zL * altA.matE.xzE ) >> altA.matE.bbpE; + vecPtrL->yE = ( y0L + xL * altA.matE.yxE + yL * altA.matE.yyE + zL * altA.matE.yzE ) >> altA.matE.bbpE; + vecPtrL->zE = ( z0L + xL * altA.matE.zxE + yL * altA.matE.zyE + zL * altA.matE.zzE ) >> altA.matE.bbpE; + vecPtrL++; + } +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Cluster3D_centerFree( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA ) +{ + struct bts_Flt16Vec3D centerL = bts_Cluster3D_center( cpA, ptrA ); + struct bts_Int16Vec3D* vecPtrL = ptrA->vecArrE; + uint32 iL; + + for( iL = ptrA->sizeE; iL > 0; iL-- ) + { + vecPtrL->xE -= centerL.xE; + vecPtrL->yE -= centerL.yE; + vecPtrL->zE -= centerL.zE; + vecPtrL++; + } + + return centerL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster3D_memSize( struct bbs_Context* cpA, + const struct bts_Cluster3D *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->sizeE ) + + bbs_SIZEOF16( ptrA->bbpE ) + + bbs_SIZEOF16( struct bts_Int16Vec3D ) * ptrA->sizeE; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster3D_memWrite( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Cluster3D_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_CLUSTER3D_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->bbpE, memPtrA ); + memPtrA += bbs_memWrite16Arr( cpA, ptrA->vecArrE, + ptrA->sizeE * bbs_SIZEOF16( struct bts_Int16Vec3D ), + memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Cluster3D_memRead( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL; + uint32 sizeL; + uint32 versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_CLUSTER3D_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &sizeL, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->bbpE, memPtrA ); + + if( ptrA->allocatedSizeE < sizeL ) + { + bts_Cluster3D_create( cpA, ptrA, sizeL, mspA ); + } + else + { + bts_Cluster3D_size( cpA, ptrA, sizeL ); + } + + + bbs_memcpy16( ptrA->vecArrE, memPtrA, bbs_SIZEOF16( struct bts_Int16Vec3D ) * ptrA->sizeE ); + memPtrA += bbs_memRead16Arr( cpA, ptrA->vecArrE, + ptrA->sizeE * bbs_SIZEOF16( struct bts_Int16Vec3D ), + memPtrA ); + + if( memSizeL != bts_Cluster3D_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Cluster3D_memRead( const struct bts_Cluster3D* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Cluster3D.h b/Embedded/common/src/b_TensorEm/Cluster3D.h new file mode 100644 index 0000000..70a75f7 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Cluster3D.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_CLUSTER3D_EM_H +#define bts_CLUSTER3D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" +#include "b_TensorEm/Int16Vec3D.h" +#include "b_TensorEm/Flt16Vec3D.h" +#include "b_TensorEm/Int16Rect.h" +#include "b_TensorEm/Flt16Alt3D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bts_CLUSTER3D_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** 3d vector array */ +struct bts_Cluster3D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** pointer to exclusive memory segment used for allocation */ + struct bbs_MemSeg* mspE; + + /** number of allocated vectors */ + uint32 allocatedSizeE; + + /** number of vectors */ + uint32 sizeE; + + /** format of vectors (bbpE always > 0) */ + int32 bbpE; + + /** array of int16 vectors */ + struct bts_Int16Vec3D* vecArrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes cluster */ +void bts_Cluster3D_init( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA ); + +/** destroys cluster */ +void bts_Cluster3D_exit( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copies cluster */ +void bts_Cluster3D_copy( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + const struct bts_Cluster3D* srcPtrA ); + +/** compares cluster */ +flag bts_Cluster3D_equal( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + const struct bts_Cluster3D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns center of gravity */ +struct bts_Flt16Vec3D bts_Cluster3D_center( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA ); + +/** returns bounding box */ +struct bts_Int16Rect bts_Cluster3D_boundingBox( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA ); + +/** returns int32 x-coordinate with given bbp at indexed position */ +int32 bts_Cluster3D_int32X( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint32 indexA, + int32 bbpA ); + +/** returns int32 y-coordinate with given bbp at indexed position */ +int32 bts_Cluster3D_int32Y( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint32 indexA, + int32 bbpA ); + +/** returns int32 z-coordinate with given bbp at indexed position */ +int32 bts_Cluster3D_int32Z( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint32 indexA, + int32 bbpA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates cluster */ +void bts_Cluster3D_create( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** resize cluster (sizeA must be smaller or equal to allocated size)*/ +void bts_Cluster3D_size( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + uint32 sizeA ); + +/** allocates cluster with external memory */ +void bts_Cluster3D_assignExternalMemory( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + struct bts_Int16Vec3D* vecArrA, + uint32 sizeA ); + +/** transforms cluster according to alt (function does not change bbp of cluster) */ +void bts_Cluster3D_transform( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + struct bts_Flt16Alt3D altA ); + +/** translates cluster such that gravity center is 0; returns former gravity center */ +struct bts_Flt16Vec3D bts_Cluster3D_centerFree( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size in words (16-bit) object needs when written to memory */ +uint32 bts_Cluster3D_memSize( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_Cluster3D_memWrite( struct bbs_Context* cpA, + const struct bts_Cluster3D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_Cluster3D_memRead( struct bbs_Context* cpA, + struct bts_Cluster3D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +#endif /* bts_CLUSTER3D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/CompactAlt.c b/Embedded/common/src/b_TensorEm/CompactAlt.c new file mode 100644 index 0000000..d1c8a95 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/CompactAlt.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/CompactAlt.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_CompactAlt_init( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA ) +{ + bts_CompactMat_init( cpA, &ptrA->matE ); + bbs_Int16Arr_init( cpA, &ptrA->vecE ); + ptrA->vecExpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_CompactAlt_exit( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA ) +{ + bts_CompactMat_exit( cpA, &ptrA->matE ); + bbs_Int16Arr_exit( cpA, &ptrA->vecE ); + ptrA->vecExpE = 0; +} +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_CompactAlt_create( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA, + uint32 widthA, + uint32 heightA, + uint32 bitsA, + uint32 maxRowSizeA, + struct bbs_MemSeg* mspA ) +{ + bts_CompactMat_create( cpA, &ptrA->matE, widthA, heightA, bitsA, maxRowSizeA, mspA ); + bbs_Int16Arr_create( cpA, &ptrA->vecE, heightA, mspA ); + bbs_Int16Arr_fill( cpA, &ptrA->vecE, 0 ); + ptrA->vecExpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_CompactAlt_copy( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA, + const struct bts_CompactAlt* srcPtrA ) +{ + bts_CompactMat_copy( cpA, &ptrA->matE, &srcPtrA->matE ); + bbs_Int16Arr_copy( cpA, &ptrA->vecE, &srcPtrA->vecE ); + ptrA->vecExpE = srcPtrA->vecExpE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_CompactAlt_memSize( struct bbs_Context* cpA, + const struct bts_CompactAlt *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bts_CompactMat_memSize( cpA, &ptrA->matE ) + + bbs_Int16Arr_memSize( cpA, &ptrA->vecE ) + + bbs_SIZEOF16( ptrA->vecExpE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_CompactAlt_memWrite( struct bbs_Context* cpA, + const struct bts_CompactAlt* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_CompactAlt_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_COMPACT_ALT_VERSION, memPtrA ); + memPtrA += bts_CompactMat_memWrite( cpA, &ptrA->matE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->vecE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->vecExpE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_CompactAlt_memRead( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_COMPACT_ALT_VERSION, memPtrA ); + memPtrA += bts_CompactMat_memRead( cpA, &ptrA->matE, memPtrA, mspA ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->vecE, memPtrA, mspA ); + memPtrA += bbs_memRead32( &ptrA->vecExpE, memPtrA ); + + if( memSizeL != bts_CompactAlt_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_CompactAlt_memRead( const struct bts_CompactAlt* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_CompactAlt_map( struct bbs_Context* cpA, + const struct bts_CompactAlt* ptrA, + const int16* inVecA, + int16 inExpA, + int16* outVecA, + int16* outExpPtrA ) +{ + uint32 iL; + uint32 sizeL = ptrA->matE.heightE; + + int32 expL = inExpA; + int16 mapExpL; + bts_CompactMat_map( cpA, &ptrA->matE, inVecA, outVecA, &mapExpL ); + expL += mapExpL; + + /* translation */ + if( ptrA->vecE.sizeE > 0 ) + { + const int16* vecL = ptrA->vecE.arrPtrE; + if( expL == ptrA->vecExpE ) + { + for( iL = 0; iL < sizeL; iL++ ) outVecA[ iL ] = ( ( int32 )outVecA[ iL ] + vecL[ iL ] + 1 ) >> 1; + expL += 1; + } + else if( expL > ptrA->vecExpE ) + { + int32 shrL = expL - ptrA->vecExpE; + int32 addL = ( int32 )1 << ( shrL - 1 ); + for( iL = 0; iL < sizeL; iL++ ) outVecA[ iL ] = ( ( int32 )outVecA[ iL ] + ( ( ( int32 )vecL[ iL ] + addL ) >> shrL ) + 1 ) >> 1; + expL += 1; + } + else + { + int32 shrL = ptrA->vecExpE - expL; + int32 addL = ( int32 )1 << ( shrL - 1 ); + for( iL = 0; iL < sizeL; iL++ ) outVecA[ iL ] = ( ( ( ( int32 )outVecA[ iL ] + addL ) >> shrL ) + vecL[ iL ] + 1 ) >> 1; + expL += 1 + shrL; + } + } + + /* precision underflow */ + if( expL < -32767 ) + { + bbs_memset16( outVecA, 0, ptrA->matE.heightE ); + expL = 0; + } + + if( outExpPtrA != NULL ) *outExpPtrA = expL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/CompactAlt.h b/Embedded/common/src/b_TensorEm/CompactAlt.h new file mode 100644 index 0000000..27188c8 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/CompactAlt.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_COMPACT_ALT_EM_H +#define bts_COMPACT_ALT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/CompactMat.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bts_COMPACT_ALT_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** Compact Affine linear trasformation composed of compact matrix and + * translation vector (not compressed) + * + * Use this object for memory efficient storage of large matrices. + */ +struct bts_CompactAlt +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** compact matrix */ + struct bts_CompactMat matE; + + /** translation vector (size = 0 when no translation) */ + struct bbs_Int16Arr vecE; + + /** exponent of translation vector */ + int32 vecExpE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes object */ +void bts_CompactAlt_init( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA ); + +/** destroys object */ +void bts_CompactAlt_exit( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* copies alt */ +void bts_CompactAlt_copy( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA, + const struct bts_CompactAlt* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates alt */ +void bts_CompactAlt_create( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA, + uint32 widthA, + uint32 heightA, + uint32 bitsA, + uint32 maxRowSizeA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_CompactAlt_memSize( struct bbs_Context* cpA, + const struct bts_CompactAlt* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_CompactAlt_memWrite( struct bbs_Context* cpA, + const struct bts_CompactAlt* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_CompactAlt_memRead( struct bbs_Context* cpA, + struct bts_CompactAlt* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + * Function executes reasonably fast with maximum possible accuracy + * inExpA - input exponent + * outExpPtrA - exponent to output vector values + */ +void bts_CompactAlt_map( struct bbs_Context* cpA, + const struct bts_CompactAlt* ptrA, + const int16* inVecA, + int16 inExpA, + int16* outVecA, + int16* outExpPtrA ); + +#endif /* bts_COMPACT_ALT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/CompactMat.c b/Embedded/common/src/b_TensorEm/CompactMat.c new file mode 100644 index 0000000..5bb44ec --- /dev/null +++ b/Embedded/common/src/b_TensorEm/CompactMat.c @@ -0,0 +1,553 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/CompactMat.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/** Returns dot product of inVec with indexed row + The result is a floating point expresstion: + upper 16 bit: signed value + lower 16 bit: signed exponent + */ +int32 bts_CompactMat_fltDotPrdRow( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + const int16* inVecA, + uint32 inNormBitsA, + uint32 rowA ) +{ + const int16* rowPtrL = ptrA->cpsArrE.arrPtrE + ptrA->wordsPerRowE * rowA; + + /* extract row-header info */ + uint32 offsL = *rowPtrL++; + uint32 sizeL = *rowPtrL++; + int32 factorManL = *rowPtrL++; + int32 factorExpL = *rowPtrL++; + uint32 rowNormBitsL = *rowPtrL++; + + /* consider possible overflow */ + uint16 overflowBitsL = ( inNormBitsA + rowNormBitsL >= 31 ) ? inNormBitsA + rowNormBitsL - 31 : 0; + + const int16* inPtrL = inVecA + offsL; + + count_t iL; + int32 sumL = 0; + + if( overflowBitsL == 0 ) /* raw dot product fits in int32 */ + { + switch( ptrA->bitsPerValueE ) + { + case 16: + { + for( iL = sizeL; iL > 0; iL-- ) sumL += ( ( int32 )*rowPtrL++ * ( int32 )*inPtrL++ ); + } + break; + + #ifndef HW_TMS320C5x /* platforms that don't have int8 must use the 'default' implementation */ + + case 8: + { + const uint16* dpL = ( uint16* )rowPtrL; + for( iL = sizeL; iL >= 8; iL -= 8 ) + { + sumL += ( ( int8 ) dpL[ 0 ] * ( int32 )inPtrL[ 0 ] ); + sumL += ( ( int8 )( dpL[ 0 ] >> 8 ) * ( int32 )inPtrL[ 1 ] ); + sumL += ( ( int8 ) dpL[ 1 ] * ( int32 )inPtrL[ 2 ] ); + sumL += ( ( int8 )( dpL[ 1 ] >> 8 ) * ( int32 )inPtrL[ 3 ] ); + sumL += ( ( int8 ) dpL[ 2 ] * ( int32 )inPtrL[ 4 ] ); + sumL += ( ( int8 )( dpL[ 2 ] >> 8 ) * ( int32 )inPtrL[ 5 ] ); + sumL += ( ( int8 ) dpL[ 3 ] * ( int32 )inPtrL[ 6 ] ); + sumL += ( ( int8 )( dpL[ 3 ] >> 8 ) * ( int32 )inPtrL[ 7 ] ); + dpL += 4; + inPtrL += 8; + } + for( ; iL >= 2; iL -= 2 ) + { + sumL += ( ( int8 ) *dpL * ( int32 )inPtrL[ 0 ] ); + sumL += ( ( int8 )( *dpL >> 8 ) * ( int32 )inPtrL[ 1 ] ); + dpL++; + inPtrL += 2; + } + if( iL > 0 ) + { + sumL += ( ( int8 )*dpL++ * ( int32 )inPtrL[ 0 ] ); + } + } + break; + + case 6: + { + const uint16* dpL = ( uint16* )rowPtrL; + for( iL = sizeL; iL >= 8; iL -= 8 ) + { + int32 lSumL = 0; + lSumL += ( ( int8 ) ( dpL[ 0 ] << 2 ) * ( int32 )inPtrL[ 0 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 0 ] >> 4 ) & 0x00FC ) * ( int32 )inPtrL[ 1 ] ); + lSumL += ( ( int8 ) ( ( ( dpL[ 0 ] >> 10 ) | ( dpL[ 1 ] << 6 ) ) & 0x00FC ) * ( int32 )inPtrL[ 2 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 1 ] ) & 0x00FC ) * ( int32 )inPtrL[ 3 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 1 ] >> 6 ) & 0x00FC ) * ( int32 )inPtrL[ 4 ] ); + lSumL += ( ( int8 ) ( ( ( dpL[ 1 ] >> 12 ) | ( dpL[ 2 ] << 4 ) ) & 0x00FC ) * ( int32 )inPtrL[ 5 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 2 ] >> 2 ) & 0x00FC ) * ( int32 )inPtrL[ 6 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 2 ] >> 8 ) & 0x00FC ) * ( int32 )inPtrL[ 7 ] ); + sumL += ( lSumL >> 2 ); + dpL += 3; + inPtrL += 8; + } + + { + int32 lSumL = 0; + if( iL > 0 ) lSumL += ( ( int8 ) ( dpL[ 0 ] << 2 ) * ( int32 )inPtrL[ 0 ] ); + if( iL > 1 ) lSumL += ( ( int8 ) ( ( dpL[ 0 ] >> 4 ) & 0x00FC ) * ( int32 )inPtrL[ 1 ] ); + if( iL > 2 ) lSumL += ( ( int8 ) ( ( ( dpL[ 0 ] >> 10 ) | ( dpL[ 1 ] << 6 ) ) & 0x00FC ) * ( int32 )inPtrL[ 2 ] ); + if( iL > 3 ) lSumL += ( ( int8 ) ( ( dpL[ 1 ] ) & 0x00FC ) * ( int32 )inPtrL[ 3 ] ); + if( iL > 4 ) lSumL += ( ( int8 ) ( ( dpL[ 1 ] >> 6 ) & 0x00FC ) * ( int32 )inPtrL[ 4 ] ); + if( iL > 5 ) lSumL += ( ( int8 ) ( ( ( dpL[ 1 ] >> 12 ) | ( dpL[ 2 ] << 4 ) ) & 0x00FC ) * ( int32 )inPtrL[ 5 ] ); + if( iL > 6 ) lSumL += ( ( int8 ) ( ( dpL[ 2 ] >> 2 ) & 0x00FC ) * ( int32 )inPtrL[ 6 ] ); + sumL += ( lSumL >> 2 ); + } + } + break; + + case 5: + { + const uint16* dpL = ( uint16* )rowPtrL; + for( iL = sizeL; iL >= 16; iL -= 16 ) + { + int32 lSumL = 0; + lSumL += ( ( int8 ) ( dpL[ 0 ] << 3 ) * ( int32 )inPtrL[ 0 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 0 ] >> 2 ) & 0x00F8 ) * ( int32 )inPtrL[ 1 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 0 ] >> 7 ) & 0x00F8 ) * ( int32 )inPtrL[ 2 ] ); + lSumL += ( ( int8 ) ( ( ( dpL[ 0 ] >> 12 ) | ( dpL[ 1 ] << 4 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 3 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 1 ] >> 1 ) & 0x00F8 ) * ( int32 )inPtrL[ 4 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 1 ] >> 6 ) & 0x00F8 ) * ( int32 )inPtrL[ 5 ] ); + lSumL += ( ( int8 ) ( ( ( dpL[ 1 ] >> 11 ) | ( dpL[ 2 ] << 5 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 6 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 2 ] ) & 0x00F8 ) * ( int32 )inPtrL[ 7 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 2 ] >> 5 ) & 0x00F8 ) * ( int32 )inPtrL[ 8 ] ); + lSumL += ( ( int8 ) ( ( ( dpL[ 2 ] >> 10 ) | ( dpL[ 3 ] << 6 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 9 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 3 ] << 1 ) & 0x00F8 ) * ( int32 )inPtrL[ 10 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 3 ] >> 4 ) & 0x00F8 ) * ( int32 )inPtrL[ 11 ] ); + lSumL += ( ( int8 ) ( ( ( dpL[ 3 ] >> 9 ) | ( dpL[ 4 ] << 7 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 12 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 4 ] << 2 ) & 0x00F8 ) * ( int32 )inPtrL[ 13 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 4 ] >> 3 ) & 0x00F8 ) * ( int32 )inPtrL[ 14 ] ); + lSumL += ( ( int8 ) ( ( dpL[ 4 ] >> 8 ) & 0x00F8 ) * ( int32 )inPtrL[ 15 ] ); + sumL += ( lSumL >> 3 ); + dpL += 5; + inPtrL += 16; + } + + { + int32 lSumL = 0; + if( iL > 0 ) lSumL += ( ( int8 ) ( dpL[ 0 ] << 3 ) * ( int32 )inPtrL[ 0 ] ); + if( iL > 1 ) lSumL += ( ( int8 ) ( ( dpL[ 0 ] >> 2 ) & 0x00F8 ) * ( int32 )inPtrL[ 1 ] ); + if( iL > 2 ) lSumL += ( ( int8 ) ( ( dpL[ 0 ] >> 7 ) & 0x00F8 ) * ( int32 )inPtrL[ 2 ] ); + if( iL > 3 ) lSumL += ( ( int8 ) ( ( ( dpL[ 0 ] >> 12 ) | ( dpL[ 1 ] << 4 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 3 ] ); + if( iL > 4 ) lSumL += ( ( int8 ) ( ( dpL[ 1 ] >> 1 ) & 0x00F8 ) * ( int32 )inPtrL[ 4 ] ); + if( iL > 5 ) lSumL += ( ( int8 ) ( ( dpL[ 1 ] >> 6 ) & 0x00F8 ) * ( int32 )inPtrL[ 5 ] ); + if( iL > 6 ) lSumL += ( ( int8 ) ( ( ( dpL[ 1 ] >> 11 ) | ( dpL[ 2 ] << 5 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 6 ] ); + if( iL > 7 ) lSumL += ( ( int8 ) ( ( dpL[ 2 ] ) & 0x00F8 ) * ( int32 )inPtrL[ 7 ] ); + if( iL > 8 ) lSumL += ( ( int8 ) ( ( dpL[ 2 ] >> 5 ) & 0x00F8 ) * ( int32 )inPtrL[ 8 ] ); + if( iL > 9 ) lSumL += ( ( int8 ) ( ( ( dpL[ 2 ] >> 10 ) | ( dpL[ 3 ] << 6 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 9 ] ); + if( iL > 10 ) lSumL += ( ( int8 ) ( ( dpL[ 3 ] << 1 ) & 0x00F8 ) * ( int32 )inPtrL[ 10 ] ); + if( iL > 11 ) lSumL += ( ( int8 ) ( ( dpL[ 3 ] >> 4 ) & 0x00F8 ) * ( int32 )inPtrL[ 11 ] ); + if( iL > 12 ) lSumL += ( ( int8 ) ( ( ( dpL[ 3 ] >> 9 ) | ( dpL[ 4 ] << 7 ) ) & 0x00F8 ) * ( int32 )inPtrL[ 12 ] ); + if( iL > 13 ) lSumL += ( ( int8 ) ( ( dpL[ 4 ] << 2 ) & 0x00F8 ) * ( int32 )inPtrL[ 13 ] ); + if( iL > 14 ) lSumL += ( ( int8 ) ( ( dpL[ 4 ] >> 3 ) & 0x00F8 ) * ( int32 )inPtrL[ 14 ] ); + sumL += ( lSumL >> 3 ); + } + } + break; + + case 4: + { + for( iL = sizeL; iL >= 4; iL -= 4 ) + { + uint16 v1L = *rowPtrL++; + int32 lSumL = 0; + lSumL += ( ( int8 )( ( v1L << 4 ) ) * ( int32 )inPtrL[ 0 ] ); + lSumL += ( ( int8 )( ( v1L ) & 0xF0 ) * ( int32 )inPtrL[ 1 ] ); + lSumL += ( ( int8 )( ( v1L >> 4 ) & 0xF0 ) * ( int32 )inPtrL[ 2 ] ); + lSumL += ( ( int8 )( ( v1L >> 8 ) & 0xF0 ) * ( int32 )inPtrL[ 3 ] ); + inPtrL += 4; + sumL += ( lSumL >> 4 ); + } + { + uint16 v1L = *rowPtrL++; + int32 lSumL = 0; + if( iL-- > 0 ) lSumL += ( ( int8 )( ( v1L << 4 ) ) * ( int32 )inPtrL[ 0 ] ); + if( iL-- > 0 ) lSumL += ( ( int8 )( ( v1L ) & 0xF0 ) * ( int32 )inPtrL[ 1 ] ); + if( iL-- > 0 ) lSumL += ( ( int8 )( ( v1L >> 4 ) & 0xF0 ) * ( int32 )inPtrL[ 2 ] ); + sumL += ( lSumL >> 4 ); + } + } + break; + + #endif /*ifndef HW_TMS320C5x*/ + + /* The default case can process all bit sizes including those that are explicitly encoded above + * Use the default for all bit sizes when the platform cannot handle the int8 data type (e.g. HW_TMS320C5x) + */ + default: + { + uint32 bfL = ( ( uint32 )*rowPtrL++ ) << 16; + uint32 bitsL = ptrA->bitsPerValueE; + uint16 adjL = 16 - bitsL; + uint32 mkL = ( ( 1 << bitsL ) - 1 ) << adjL; + uint32 srL = bitsL; + for( iL = 0; iL < sizeL; iL++ ) + { + if( srL > 16 ) + { + bfL = ( ( ( uint32 )*rowPtrL++ ) << 16 ) | ( bfL >> 16 ); + srL -= 16; + } + sumL += ( ( int16 )( ( bfL >> srL ) & mkL ) * ( int32 )inPtrL[ iL ] ) >> adjL; + srL += bitsL; + } + } + } + } + else /* raw dot product does not fit in int32 */ + { + int32 roundL = 1 << ( overflowBitsL - 1 ); + switch( ptrA->bitsPerValueE ) + { + case 16: + { + for( iL = sizeL; iL > 0; iL-- ) sumL += ( ( ( int32 )*rowPtrL++ * ( int32 )*inPtrL++ ) + roundL ) >> overflowBitsL; + } + break; + + case 8: + { + for( iL = sizeL; iL >= 2; iL -= 2 ) + { + uint16 v1L = *rowPtrL++; + int32 lSumL = ( ( int8 ) v1L * ( int32 )inPtrL[ 0 ] ) + + ( ( int8 )( v1L >> 8 ) * ( int32 )inPtrL[ 1 ] ); + sumL += ( lSumL + roundL ) >> overflowBitsL; + inPtrL += 2; + } + if( iL > 0 ) + { + sumL += ( ( ( int8 )*rowPtrL++ * ( int32 )inPtrL[ 0 ] ) + roundL ) >> overflowBitsL; + } + } + break; + + case 4: + { + for( iL = sizeL; iL >= 4; iL -= 4 ) + { + uint16 v1L = *rowPtrL++; + int32 lSumL = 0; + lSumL += ( ( int8 )( ( v1L << 4 ) ) * ( int32 )inPtrL[ 0 ] ); + lSumL += ( ( int8 )( ( v1L ) & 0xF0 ) * ( int32 )inPtrL[ 1 ] ); + lSumL += ( ( int8 )( ( v1L >> 4 ) & 0xF0 ) * ( int32 )inPtrL[ 2 ] ); + lSumL += ( ( int8 )( ( v1L >> 8 ) & 0xF0 ) * ( int32 )inPtrL[ 3 ] ); + inPtrL += 4; + sumL += ( ( lSumL >> 4 ) + roundL ) >> overflowBitsL; + } + { + uint16 v1L = *rowPtrL++; + int32 lSumL = 0; + if( iL-- > 0 ) lSumL += ( ( int8 )( ( v1L << 4 ) ) * ( int32 )inPtrL[ 0 ] ); + if( iL-- > 0 ) lSumL += ( ( int8 )( ( v1L ) & 0xF0 ) * ( int32 )inPtrL[ 1 ] ); + if( iL-- > 0 ) lSumL += ( ( int8 )( ( v1L >> 4 ) & 0xF0 ) * ( int32 )inPtrL[ 2 ] ); + sumL += ( ( lSumL >> 4 ) + roundL ) >> overflowBitsL; + } + } + break; + + default: + { + uint32 bfL = ( ( uint32 )*rowPtrL++ ) << 16; + uint32 bitsL = ptrA->bitsPerValueE; + uint16 adjL = 16 - bitsL; + uint32 mkL = ( ( 1 << bitsL ) - 1 ) << adjL; + uint32 srL = bitsL; + int32 lRoundL = roundL << adjL; + int32 lAdjL = overflowBitsL + adjL; + for( iL = 0; iL < sizeL; iL++ ) + { + if( srL > 16 ) + { + bfL = ( ( ( uint32 )*rowPtrL++ ) << 16 ) | ( bfL >> 16 ); + srL -= 16; + } + sumL += ( ( int16 )( ( bfL >> srL ) & mkL ) * ( int32 )inPtrL[ iL ] + lRoundL ) >> lAdjL; + srL += bitsL; + } + } + } + } + + /* compute result */ + { + int32 resultManL; + int32 resultExpL; + int32 resultLogL; + bbs_mulS32( sumL, factorManL, &resultManL, &resultExpL ); + resultExpL += factorExpL + overflowBitsL; + resultLogL = bbs_intLog2( resultManL > 0 ? resultManL : -resultManL ); + if( resultLogL < 30 ) + { + resultManL <<= 30 - resultLogL; + resultExpL -= 30 - resultLogL; + } + + resultManL = ( ( resultManL >> 15 ) + 1 ) >> 1; + resultExpL = resultExpL + 16; + + return ( ( resultManL & 0x0000FFFF ) << 16 ) | ( resultExpL & 0x0000FFFF ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_CompactMat_init( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA ) +{ + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->bitsPerValueE = 0; + ptrA->wordsPerRowE = 0; + ptrA->maxRowBitsE = 0; + bbs_Int16Arr_init( cpA, &ptrA->cpsArrE ); + bbs_Int16Arr_init( cpA, &ptrA->expArrE ); + +} + +/* ------------------------------------------------------------------------- */ + +void bts_CompactMat_exit( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA ) +{ + ptrA->widthE = 0; + ptrA->heightE = 0; + ptrA->bitsPerValueE = 0; + ptrA->wordsPerRowE = 0; + ptrA->maxRowBitsE = 0; + bbs_Int16Arr_exit( cpA, &ptrA->cpsArrE ); + bbs_Int16Arr_exit( cpA, &ptrA->expArrE ); +} +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_CompactMat_create( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + uint32 widthA, + uint32 heightA, + uint32 bitsA, + uint32 maxRowSizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + if( bitsA < 2 || bitsA > 16 ) + { + bbs_ERROR0( "bts_CompactMat_create:\nbitsA must be between 2 and 16" ); + return; + } + + ptrA->widthE = widthA; + ptrA->heightE = heightA; + ptrA->bitsPerValueE = bitsA; + ptrA->wordsPerRowE = 6 /*header + 1*/ + ( ( maxRowSizeA * bitsA ) / ( 8 * sizeof( short ) ) ); + ptrA->maxRowBitsE = 0; + if( ( ptrA->wordsPerRowE & 1 ) != 0 ) ptrA->wordsPerRowE++; + bbs_Int16Arr_create( cpA, &ptrA->cpsArrE, heightA * ptrA->wordsPerRowE, mspA ); + bbs_Int16Arr_fill( cpA, &ptrA->cpsArrE, 0 ); + bbs_Int16Arr_create( cpA, &ptrA->expArrE, ptrA->heightE, mspA ); + bbs_Int16Arr_fill( cpA, &ptrA->expArrE, 0 ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_CompactMat_copy( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + const struct bts_CompactMat* srcPtrA ) +{ + ptrA->widthE = srcPtrA->widthE; + ptrA->heightE = srcPtrA->heightE; + ptrA->bitsPerValueE = srcPtrA->bitsPerValueE; + ptrA->wordsPerRowE = srcPtrA->wordsPerRowE; + ptrA->maxRowBitsE = srcPtrA->maxRowBitsE; + bbs_Int16Arr_copy( cpA, &ptrA->cpsArrE, &srcPtrA->cpsArrE ); + bbs_Int16Arr_size( cpA, &ptrA->expArrE, ptrA->heightE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_CompactMat_memSize( struct bbs_Context* cpA, + const struct bts_CompactMat *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_SIZEOF16( ptrA->heightE ) + + bbs_SIZEOF16( ptrA->bitsPerValueE ) + + bbs_SIZEOF16( ptrA->wordsPerRowE ) + + bbs_SIZEOF16( ptrA->maxRowBitsE ) + + bbs_Int16Arr_memSize( cpA, &ptrA->cpsArrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_CompactMat_memWrite( struct bbs_Context* cpA, + const struct bts_CompactMat* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_CompactMat_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_COMPACT_MAT_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->bitsPerValueE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->wordsPerRowE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->maxRowBitsE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->cpsArrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_CompactMat_memRead( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_COMPACT_MAT_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->heightE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->bitsPerValueE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->wordsPerRowE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->maxRowBitsE, memPtrA ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->cpsArrE, memPtrA, mspA ); + + if( memSizeL != bts_CompactMat_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_CompactMat_memRead( const struct bts_CompactMat* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + } + + bbs_Int16Arr_create( cpA, &ptrA->expArrE, ptrA->heightE, mspA ); + bbs_Int16Arr_fill( cpA, &ptrA->expArrE, 0 ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_CompactMat_map( struct bbs_Context* cpA, + const struct bts_CompactMat* ptrA, + const int16* inVecA, + int16* outVecA, + int16* outExpPtrA ) +{ + uint32 inNormBitsL = bbs_intLog2( bbs_vecNorm16( inVecA, ptrA->widthE ) ) + 1; + uint32 iL; + + int16* expArrL = ( ( struct bts_CompactMat* )ptrA )->expArrE.arrPtrE; + int16 maxExpL = -32767; + + for( iL = 0; iL < ptrA->heightE; iL++ ) + { + int32 fltL = bts_CompactMat_fltDotPrdRow( cpA, ( struct bts_CompactMat* )ptrA, inVecA, inNormBitsL, iL ); + outVecA[ iL ] = fltL >> 16; + expArrL[ iL ] = fltL & 0x0000FFFF; + + maxExpL = ( expArrL[ iL ] > maxExpL ) ? expArrL[ iL ] : maxExpL; + } + + if( outExpPtrA != NULL ) *outExpPtrA = maxExpL; + + for( iL = 0; iL < ptrA->heightE; iL++ ) + { + int32 shrL = maxExpL - expArrL[ iL ]; + if( shrL > 0 ) + { + outVecA[ iL ] = ( ( outVecA[ iL ] >> ( shrL - 1 ) ) + 1 ) >> 1; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/CompactMat.h b/Embedded/common/src/b_TensorEm/CompactMat.h new file mode 100644 index 0000000..c6fbd31 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/CompactMat.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_COMPACT_MAT_EM_H +#define bts_COMPACT_MAT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Int16Arr.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bts_COMPACT_MAT_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** Compact Matrix + * This object represents a general nxm Matrix that stores its values in + * bit-packs of fixed size. Rows are encoded individually to yield + * maximum accuracy for the given number of bits. The matrix takes sparseness + * into account. + * + * Use this object for memory efficient storage of large matrices. + */ +struct bts_CompactMat +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /* width (columns) of matrix */ + uint32 widthE; + + /* height (rows) of matrix */ + uint32 heightE; + + /* bits per value */ + uint32 bitsPerValueE; + + /* 16 bit words per row including row-header (always even) */ + uint32 wordsPerRowE; + + /* maximum of ( 16 + factorExp + normBits ) for all rows (this value can be negative!) */ + int32 maxRowBitsE; + + /** Composite data array + * Encoding per row: + * (int16) 'offs' offset of row-vector (0 when row is not sparse) + * (int16) 'size' effective size of row vector (= widthE when row is not sparse) + * (int16) 'factorMan' mantisse of factor + * (int16) 'factorExp' exponent of factor + * (int16) 'normBits' norm bits of row vector + * (int16), (int16), ... packed data + * Each row has the effective length of 'wordsPerRowE' + * wordsPerRowE is always even -> rows are 32bit-aligned + */ + struct bbs_Int16Arr cpsArrE; + + /** temorary array used for exponents */ + struct bbs_Int16Arr expArrE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes object */ +void bts_CompactMat_init( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA ); + +/** destroys object */ +void bts_CompactMat_exit( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* copies matrix */ +void bts_CompactMat_copy( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + const struct bts_CompactMat* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates matrix */ +void bts_CompactMat_create( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + uint32 widthA, + uint32 heightA, + uint32 bitsA, + uint32 maxRowSizeA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_CompactMat_memSize( struct bbs_Context* cpA, + const struct bts_CompactMat* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_CompactMat_memWrite( struct bbs_Context* cpA, + const struct bts_CompactMat* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_CompactMat_memRead( struct bbs_Context* cpA, + struct bts_CompactMat* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + * Function executes reasonably fast with maximum possible accuracy + * outExpPtrA - exponent to output vector values + */ +void bts_CompactMat_map( struct bbs_Context* cpA, + const struct bts_CompactMat* ptrA, + const int16* inVecA, + int16* outVecA, + int16* outExpPtrA ); + +#endif /* bts_COMPACT_MAT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Alt2D.c b/Embedded/common/src/b_TensorEm/Flt16Alt2D.c new file mode 100644 index 0000000..dd6189c --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Alt2D.c @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Alt2D.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Alt2D_init( struct bts_Flt16Alt2D* ptrA ) +{ + bts_Flt16Mat2D_init( &ptrA->matE ); + bts_Flt16Vec2D_init( &ptrA->vecE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Alt2D_exit( struct bts_Flt16Alt2D* ptrA ) +{ + bts_Flt16Mat2D_exit( &ptrA->matE ); + bts_Flt16Vec2D_exit( &ptrA->vecE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Alt2D_copy( struct bts_Flt16Alt2D* ptrA, const struct bts_Flt16Alt2D* srcPtrA ) +{ + bts_Flt16Mat2D_copy( &ptrA->matE, &srcPtrA->matE ); + bts_Flt16Vec2D_copy( &ptrA->vecE, &srcPtrA->vecE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Flt16Alt2D_equal( const struct bts_Flt16Alt2D* ptrA, const struct bts_Flt16Alt2D* srcPtrA ) +{ + if( ! bts_Flt16Mat2D_equal( &ptrA->matE, &srcPtrA->matE ) ) return FALSE; + if( ! bts_Flt16Vec2D_equal( &ptrA->vecE, &srcPtrA->vecE ) ) return FALSE; + return TRUE; +} + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Alt2D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Alt2D *ptrA ) +{ + bbs_ERROR0( "unimplemented function" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Alt2D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Alt2D* ptrA, + uint16* memPtrA ) +{ + bbs_ERROR0( "unimplemented function" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Alt2D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Alt2D* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + bbs_ERROR0( "unimplemented function" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_createIdentity() +{ + struct bts_Flt16Alt2D altL = { { 1, 0, 0, 1, 0 }, { 0, 0, 0 } }; + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_createRotation( phase16 angleA, + const struct bts_Flt16Vec2D* centerPtrA ) +{ + struct bts_Flt16Alt2D altL; + altL.matE = bts_Flt16Mat2D_createRotation( angleA ); + altL.vecE = bts_Flt16Vec2D_sub( *centerPtrA, bts_Flt16Mat2D_mapFlt( &altL.matE, centerPtrA ) ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_createScale( int32 scaleA, + int32 scaleBbpA, + const struct bts_Flt16Vec2D* centerPtrA ) +{ + struct bts_Flt16Alt2D altL; + altL.matE = bts_Flt16Mat2D_createScale( scaleA, scaleBbpA ); + altL.vecE = bts_Flt16Vec2D_sub( *centerPtrA, bts_Flt16Mat2D_mapFlt( &altL.matE, centerPtrA ) ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_createRigid( phase16 angleA, + int32 scaleA, + int32 scaleBbpA, + const struct bts_Flt16Vec2D* centerPtrA ) +{ + struct bts_Flt16Alt2D altL; + altL.matE = bts_Flt16Mat2D_createRigid( angleA, scaleA, scaleBbpA ); + altL.vecE = bts_Flt16Vec2D_sub( *centerPtrA, bts_Flt16Mat2D_mapFlt( &altL.matE, centerPtrA ) ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_createRigidMap( struct bts_Flt16Vec2D vecIn1A, + struct bts_Flt16Vec2D vecIn2A, + struct bts_Flt16Vec2D vecOut1A, + struct bts_Flt16Vec2D vecOut2A ) +{ + struct bts_Flt16Vec2D diffInL = bts_Flt16Vec2D_sub( vecIn1A, vecIn2A ); + struct bts_Flt16Vec2D diffOutL = bts_Flt16Vec2D_sub( vecOut1A, vecOut2A ); + struct bts_Flt16Vec2D centerInL = bts_Flt16Vec2D_mul( bts_Flt16Vec2D_add( vecIn1A, vecIn2A ), 1, 1 ); /* mul by 0.5 */ + struct bts_Flt16Vec2D centerOutL = bts_Flt16Vec2D_mul( bts_Flt16Vec2D_add( vecOut1A, vecOut2A ), 1, 1 ); /* mul by 0.5 */ + + struct bts_Flt16Vec2D transL = bts_Flt16Vec2D_sub( centerOutL, centerInL ); + phase16 angleL = bts_Flt16Vec2D_enclosedAngle( &diffOutL, &diffInL ); + uint32 normInL = bts_Flt16Vec2D_norm( &diffInL ); + uint32 normOutL = bts_Flt16Vec2D_norm( &diffOutL ); + + uint32 scaleL = ( normInL > 0 ) ? ( normOutL << 16 ) / normInL : 0xFFFFFFFF; + uint32 scaleBbpL = 16 + diffOutL.bbpE - diffInL.bbpE; + + struct bts_Flt16Alt2D altL; + + /* fit scale factor in 15 bit */ + uint32 scaleExpL = bbs_intLog2( scaleL ); + if( scaleExpL > 14 ) + { + scaleL >>= scaleExpL - 14; + scaleBbpL -= scaleExpL - 14; + } + + altL = bts_Flt16Alt2D_createRigid( angleL, ( int16 )scaleL, scaleBbpL, ¢erInL ); + + altL.vecE = bts_Flt16Vec2D_add( altL.vecE, transL ); + + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_create16( int16 xxA, + int16 xyA, + int16 yxA, + int16 yyA, + int16 matBbpA, + int16 xA, + int16 yA, + int16 vecBbpA ) +{ + struct bts_Flt16Alt2D altL; + altL.matE = bts_Flt16Mat2D_create16( xxA, xyA, yxA, yyA, matBbpA ); + altL.vecE = bts_Flt16Vec2D_create16( xA, yA, vecBbpA ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_create32( int32 xxA, + int32 xyA, + int32 yxA, + int32 yyA, + int32 matBbpA, + int32 xA, + int32 yA, + int32 vecBbpA ) +{ + struct bts_Flt16Alt2D altL; + altL.matE = bts_Flt16Mat2D_create32( xxA, xyA, yxA, yyA, matBbpA ); + altL.vecE = bts_Flt16Vec2D_create32( xA, yA, vecBbpA ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Alt2D_mapFlt( const struct bts_Flt16Alt2D* altPtrA, + const struct bts_Flt16Vec2D* vecPtrA ) +{ + return bts_Flt16Vec2D_add( altPtrA->vecE, bts_Flt16Mat2D_mapFlt( &altPtrA->matE, vecPtrA ) ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_mul( const struct bts_Flt16Alt2D* alt1PtrA, + const struct bts_Flt16Alt2D* alt2PtrA ) +{ + struct bts_Flt16Alt2D altL; + altL.vecE = bts_Flt16Alt2D_mapFlt( alt1PtrA, &alt2PtrA->vecE ); + altL.matE = bts_Flt16Mat2D_mul( &alt1PtrA->matE, &alt2PtrA->matE ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +/** multiplies matrix with matA; returns pointer to resulting matrix */ +struct bts_Flt16Alt2D* bts_Flt16Alt2D_mulTo( struct bts_Flt16Alt2D* alt1PtrA, + const struct bts_Flt16Alt2D* alt2PtrA ) +{ + *alt1PtrA = bts_Flt16Alt2D_mul( alt1PtrA, alt2PtrA ); + return alt1PtrA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Alt2D_invert( struct bts_Flt16Alt2D* ptrA ) +{ + bts_Flt16Mat2D_invert( &ptrA->matE ); + + ptrA->vecE = bts_Flt16Vec2D_create32( - ( ( ( int32 ) ptrA->matE.xxE * ptrA->vecE.xE + ( int32 ) ptrA->matE.xyE * ptrA->vecE.yE ) ), + - ( ( ( int32 ) ptrA->matE.yxE * ptrA->vecE.xE + ( int32 ) ptrA->matE.yyE * ptrA->vecE.yE ) ), + ptrA->vecE.bbpE + ptrA->matE.bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_Flt16Alt2D_inverted( const struct bts_Flt16Alt2D* ptrA ) +{ + struct bts_Flt16Alt2D altL = *ptrA; + bts_Flt16Alt2D_invert( &altL ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Flt16Alt2D.h b/Embedded/common/src/b_TensorEm/Flt16Alt2D.h new file mode 100644 index 0000000..4103bbe --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Alt2D.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT16ALT2D_EM_H +#define bts_FLT16ALT2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_TensorEm/Flt16Mat2D.h" +#include "b_TensorEm/Flt16Vec2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d affine linear trafo */ +struct bts_Flt16Alt2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** matrix */ + struct bts_Flt16Mat2D matE; + + /** vector */ + struct bts_Flt16Vec2D vecE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes alt */ +void bts_Flt16Alt2D_init( struct bts_Flt16Alt2D* ptrA ); + +/** destroys alt */ +void bts_Flt16Alt2D_exit( struct bts_Flt16Alt2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_Flt16Alt2D_copy( struct bts_Flt16Alt2D* ptrA, + const struct bts_Flt16Alt2D* srcPtrA ); + +/** equal operator */ +flag bts_Flt16Alt2D_equal( const struct bts_Flt16Alt2D* ptrA, + const struct bts_Flt16Alt2D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Flt16Alt2D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Alt2D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Flt16Alt2D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Alt2D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Flt16Alt2D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Alt2D* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** inverts alt */ +void bts_Flt16Alt2D_invert( struct bts_Flt16Alt2D* ptrA ); + +/** returns inverted alt */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_inverted( const struct bts_Flt16Alt2D* ptrA ); + +/** creates identity alt */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_createIdentity( void ); + +/** creates rotation alt */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_createRotation( phase16 angleA, + const struct bts_Flt16Vec2D* centerPtrA ); + +/** creates scale alt */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_createScale( int32 scaleA, + int32 scaleBbpA, + const struct bts_Flt16Vec2D* centerPtrA ); + +/** creates rigid alt (scale & rotation) */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_createRigid( phase16 angleA, + int32 scaleA, + int32 scaleBbpA, + const struct bts_Flt16Vec2D* centerPtrA ); + +/** creates rigid alt (scale & rotation) that mapps vecIn1 and vecIn2 to vecOut1 and vecOut2*/ +struct bts_Flt16Alt2D bts_Flt16Alt2D_createRigidMap( struct bts_Flt16Vec2D vecIn1A, + struct bts_Flt16Vec2D vecIn2A, + struct bts_Flt16Vec2D vecOut1A, + struct bts_Flt16Vec2D vecOut2A ); + +/** creates alt from 16 bit values */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_create16( int16 xxA, + int16 xyA, + int16 yxA, + int16 yyA, + int16 matBbpA, + int16 xA, + int16 yA, + int16 vecBbpA ); + +/** creates alt from 32 bit values (automatic adjustment of bbp value) */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_create32( int32 xxA, + int32 xyA, + int32 yxA, + int32 yyA, + int32 matBbpA, + int32 xA, + int32 yA, + int32 vecBbpA ); + +/** Multiplies matrix with float vecA; returns resulting vector. + * bbp can get changed. + */ +struct bts_Flt16Vec2D bts_Flt16Alt2D_mapFlt( const struct bts_Flt16Alt2D* matPtrA, + const struct bts_Flt16Vec2D* vecPtrA ); + +/** multiplies alt with altA returns resulting alt */ +struct bts_Flt16Alt2D bts_Flt16Alt2D_mul( const struct bts_Flt16Alt2D* alt1PtrA, + const struct bts_Flt16Alt2D* alt2PtrA ); + +/** multiplies alt with matA; returns pointer to resulting alt */ +struct bts_Flt16Alt2D* bts_Flt16Alt2D_mulTo( struct bts_Flt16Alt2D* alt1PtrA, + const struct bts_Flt16Alt2D* alt2PtrA ); + +#endif /* bts_FLT16ALT2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Alt3D.c b/Embedded/common/src/b_TensorEm/Flt16Alt3D.c new file mode 100644 index 0000000..16a25da --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Alt3D.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Alt3D.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Alt3D_init( struct bts_Flt16Alt3D* ptrA ) +{ + bts_Flt16Mat3D_init( &ptrA->matE ); + bts_Flt16Vec3D_init( &ptrA->vecE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Alt3D_exit( struct bts_Flt16Alt3D* ptrA ) +{ + bts_Flt16Mat3D_exit( &ptrA->matE ); + bts_Flt16Vec3D_exit( &ptrA->vecE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Alt3D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Alt3D *ptrA ) +{ + bbs_ERROR0( "unimplemented function" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Alt3D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Alt3D* ptrA, + uint16* memPtrA ) +{ + bbs_ERROR0( "unimplemented function" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Alt3D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Alt3D* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + bbs_ERROR0( "unimplemented function" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt3D bts_Flt16Alt3D_createIdentity() +{ + struct bts_Flt16Alt3D altL = { { 1, 0, 0, + 0, 1, 0, + 0, 0, 1, 0 }, { 0, 0, 0, 0 } }; + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt3D bts_Flt16Alt3D_createScale( int32 scaleA, + int32 scaleBbpA, + const struct bts_Flt16Vec3D* centerPtrA ) +{ + struct bts_Flt16Alt3D altL; + altL.matE = bts_Flt16Mat3D_createScale( scaleA, scaleBbpA ); + altL.vecE = bts_Flt16Vec3D_sub( *centerPtrA, bts_Flt16Mat3D_mapFlt( &altL.matE, centerPtrA ) ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt3D bts_Flt16Alt3D_createLinear( const struct bts_Flt16Mat3D* matPtrA, + const struct bts_Flt16Vec3D* centerPtrA ) +{ + struct bts_Flt16Alt3D altL; + altL.matE = *matPtrA; + altL.vecE = bts_Flt16Vec3D_sub( *centerPtrA, bts_Flt16Mat3D_mapFlt( &altL.matE, centerPtrA ) ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt3D bts_Flt16Alt3D_create16( int16 xxA, int16 xyA, int16 xzA, + int16 yxA, int16 yyA, int16 yzA, + int16 zxA, int16 zyA, int16 zzA, + int16 matBbpA, + int16 xA, int16 yA, int16 zA, + int16 vecBbpA ) +{ + struct bts_Flt16Alt3D altL; + altL.matE = bts_Flt16Mat3D_create16( xxA, xyA, xzA, + yxA, yyA, yzA, + zxA, zyA, zzA, + matBbpA ); + + altL.vecE = bts_Flt16Vec3D_create16( xA, yA, zA, vecBbpA ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt3D bts_Flt16Alt3D_create32( int32 xxA, int32 xyA, int32 xzA, + int32 yxA, int32 yyA, int32 yzA, + int32 zxA, int32 zyA, int32 zzA, + int16 matBbpA, + int32 xA, int32 yA, int32 zA, + int16 vecBbpA ) +{ + struct bts_Flt16Alt3D altL; + altL.matE = bts_Flt16Mat3D_create32( xxA, xyA, xzA, + yxA, yyA, yzA, + zxA, zyA, zzA, + matBbpA ); + + altL.vecE = bts_Flt16Vec3D_create32( xA, yA, zA, vecBbpA ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Alt3D_mapFlt( const struct bts_Flt16Alt3D* altPtrA, + const struct bts_Flt16Vec3D* vecPtrA ) +{ + struct bts_Flt16Vec3D vecL = bts_Flt16Mat3D_mapFlt( &altPtrA->matE, vecPtrA ); + int32 shiftL = altPtrA->vecE.bbpE - vecL.bbpE; + if( shiftL > 0 ) + { + int32 sh1L = shiftL - 1; + vecL.xE += ( ( altPtrA->vecE.xE >> sh1L ) + 1 ) >> 1; + vecL.yE += ( ( altPtrA->vecE.yE >> sh1L ) + 1 ) >> 1; + vecL.zE += ( ( altPtrA->vecE.zE >> sh1L ) + 1 ) >> 1; + } + else + { + vecL.xE += altPtrA->vecE.xE << -shiftL; + vecL.yE += altPtrA->vecE.yE << -shiftL; + vecL.zE += altPtrA->vecE.zE << -shiftL; + } + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt3D bts_Flt16Alt3D_mul( const struct bts_Flt16Alt3D* alt1PtrA, + const struct bts_Flt16Alt3D* alt2PtrA ) +{ + struct bts_Flt16Alt3D altL; + altL.vecE = bts_Flt16Alt3D_mapFlt( alt1PtrA, &alt2PtrA->vecE ); + altL.matE = bts_Flt16Mat3D_mul( &alt1PtrA->matE, &alt2PtrA->matE ); + return altL; +} + +/* ------------------------------------------------------------------------- */ + +/** multiplies matrix with matA; returns pointer to resulting matrix */ +struct bts_Flt16Alt3D* bts_Flt16Alt3D_mulTo( struct bts_Flt16Alt3D* alt1PtrA, + const struct bts_Flt16Alt3D* alt2PtrA ) +{ + *alt1PtrA = bts_Flt16Alt3D_mul( alt1PtrA, alt2PtrA ); + return alt1PtrA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Alt3D.h b/Embedded/common/src/b_TensorEm/Flt16Alt3D.h new file mode 100644 index 0000000..fe3d781 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Alt3D.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT16ALT3D_EM_H +#define bts_FLT16ALT3D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_TensorEm/Flt16Mat3D.h" +#include "b_TensorEm/Flt16Vec3D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 3d affine linear trafo */ +struct bts_Flt16Alt3D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** matrix */ + struct bts_Flt16Mat3D matE; + + /** vector */ + struct bts_Flt16Vec3D vecE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes alt */ +void bts_Flt16Alt3D_init( struct bts_Flt16Alt3D* ptrA ); + +/** destroys alt */ +void bts_Flt16Alt3D_exit( struct bts_Flt16Alt3D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Flt16Alt3D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Alt3D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Flt16Alt3D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Alt3D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Flt16Alt3D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Alt3D* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creates identity alt */ +struct bts_Flt16Alt3D bts_Flt16Alt3D_createIdentity( void ); + +/** creates scale alt */ +struct bts_Flt16Alt3D bts_Flt16Alt3D_createScale( int32 scaleA, + int32 scaleBbpA, + const struct bts_Flt16Vec3D* centerPtrA ); + +/** creates linear alt from matrix and center */ +struct bts_Flt16Alt3D bts_Flt16Alt3D_createLinear( const struct bts_Flt16Mat3D* matPtrA, + const struct bts_Flt16Vec3D* centerPtrA ); + +/** creates alt from 16 bit values */ +struct bts_Flt16Alt3D bts_Flt16Alt3D_create16( int16 xxA, int16 xyA, int16 xzA, + int16 yxA, int16 yyA, int16 yzA, + int16 zxA, int16 zyA, int16 zzA, + int16 matBbpA, + int16 xA, int16 yA, int16 zA, + int16 vecBbpA ); + +/** creates alt from 32 bit values (automatic adjustment of bbp value) */ +struct bts_Flt16Alt3D bts_Flt16Alt3D_create32( int32 xxA, int32 xyA, int32 xzA, + int32 yxA, int32 yyA, int32 yzA, + int32 zxA, int32 zyA, int32 zzA, + int16 matBbpA, + int32 xA, int32 yA, int32 zA, + int16 vecBbpA ); + +/** Multiplies matrix with float vecA; returns resulting vector */ +struct bts_Flt16Vec3D bts_Flt16Alt3D_mapFlt( const struct bts_Flt16Alt3D* matPtrA, + const struct bts_Flt16Vec3D* vecPtrA ); + +/** multiplies alt with altA returns resulting alt */ +struct bts_Flt16Alt3D bts_Flt16Alt3D_mul( const struct bts_Flt16Alt3D* mat1PtrA, + const struct bts_Flt16Alt3D* mat2PtrA ); + +/** multiplies alt with matA; returns pointer to resulting alt */ +struct bts_Flt16Alt3D* bts_Flt16Alt3D_mulTo( struct bts_Flt16Alt3D* mat1PtrA, + const struct bts_Flt16Alt3D* mat2PtrA ); + +#endif /* bts_FLT16ALT3D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Mat2D.c b/Embedded/common/src/b_TensorEm/Flt16Mat2D.c new file mode 100644 index 0000000..4099167 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Mat2D.c @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Mat2D.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat2D_init( struct bts_Flt16Mat2D* ptrA ) +{ + ptrA->bbpE = 0; + ptrA->xxE = 0; + ptrA->xyE = 0; + ptrA->yxE = 0; + ptrA->yyE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat2D_exit( struct bts_Flt16Mat2D* ptrA ) +{ + ptrA->bbpE = 0; + ptrA->xxE = 0; + ptrA->xyE = 0; + ptrA->yxE = 0; + ptrA->yyE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat2D_copy( struct bts_Flt16Mat2D* ptrA, const struct bts_Flt16Mat2D* srcPtrA ) +{ + ptrA->bbpE = srcPtrA->bbpE; + ptrA->xxE = srcPtrA->xxE; + ptrA->xyE = srcPtrA->xyE; + ptrA->yxE = srcPtrA->yxE; + ptrA->yyE = srcPtrA->yyE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Flt16Mat2D_equal( const struct bts_Flt16Mat2D* ptrA, const struct bts_Flt16Mat2D* srcPtrA ) +{ + int32 bbpDiffL = ptrA->bbpE - srcPtrA->bbpE; + if( bbpDiffL == 0 ) + { + if( ptrA->xxE != srcPtrA->xxE ) return FALSE; + if( ptrA->xyE != srcPtrA->xyE ) return FALSE; + if( ptrA->yxE != srcPtrA->yxE ) return FALSE; + if( ptrA->yyE != srcPtrA->yyE ) return FALSE; + return TRUE; + } + + if( bbpDiffL > 0 ) + { + int32 xxL = ( int32 ) srcPtrA->xxE << bbpDiffL; + int32 xyL = ( int32 ) srcPtrA->xyE << bbpDiffL; + int32 yxL = ( int32 ) srcPtrA->yxE << bbpDiffL; + int32 yyL = ( int32 ) srcPtrA->yyE << bbpDiffL; + + if( ptrA->xxE != xxL ) return FALSE; + if( ptrA->xyE != xyL ) return FALSE; + if( ptrA->yxE != yxL ) return FALSE; + if( ptrA->yyE != yyL ) return FALSE; + + /* check if bits were lost by the shifting */ + if( srcPtrA->xxE != ( xxL >> bbpDiffL ) ) return FALSE; + if( srcPtrA->xyE != ( xyL >> bbpDiffL ) ) return FALSE; + if( srcPtrA->yxE != ( yxL >> bbpDiffL ) ) return FALSE; + if( srcPtrA->yyE != ( yyL >> bbpDiffL ) ) return FALSE; + + return TRUE; + } + + if( bbpDiffL < 0 ) + { + int32 xxL = ( int32 ) ptrA->xxE << -bbpDiffL; + int32 xyL = ( int32 ) ptrA->xyE << -bbpDiffL; + int32 yxL = ( int32 ) ptrA->yxE << -bbpDiffL; + int32 yyL = ( int32 ) ptrA->yyE << -bbpDiffL; + + if( xxL != srcPtrA->xxE ) return FALSE; + if( xyL != srcPtrA->xyE ) return FALSE; + if( yxL != srcPtrA->yxE ) return FALSE; + if( yyL != srcPtrA->yyE ) return FALSE; + + /* check if bits were lost by the shifting */ + if( ptrA->xxE != ( xxL >> -bbpDiffL ) ) return FALSE; + if( ptrA->xyE != ( xyL >> -bbpDiffL ) ) return FALSE; + if( ptrA->yxE != ( yxL >> -bbpDiffL ) ) return FALSE; + if( ptrA->yyE != ( yyL >> -bbpDiffL ) ) return FALSE; + + return TRUE; + } + + return TRUE; +} + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Mat2D_det( const struct bts_Flt16Mat2D* ptrA ) +{ + /* This could be negativ, in theory. But almost always det > 0 for us, + matrix is a rotation or scaling matrix. + Then uint32 makes sure there is no overflow. */ + uint32 detL = ( int32 ) ptrA->xxE * ptrA->yyE - ( int32 ) ptrA->xyE * ptrA->yxE; + return detL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_createIdentity() +{ + struct bts_Flt16Mat2D matL = { 1 << 14, 0, 0, 1 << 14, 14 }; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_createRotation( phase16 angleA ) +{ + int16 cL = bbs_cos16( angleA ); + int16 sL = bbs_sin16( angleA ); + struct bts_Flt16Mat2D matL; + matL.xxE = cL; + matL.xyE = -sL; + matL.yxE = sL; + matL.yyE = cL; + matL.bbpE = 14; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_createScale( int32 scaleA, int32 scaleBbpA ) +{ + struct bts_Flt16Mat2D matL = bts_Flt16Mat2D_createIdentity(); + bts_Flt16Mat2D_scale( &matL, scaleA, scaleBbpA ); + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_createRigid( phase16 angleA, int32 scaleA, int32 scaleBbpA ) +{ + struct bts_Flt16Mat2D matL = bts_Flt16Mat2D_createRotation( angleA ); + bts_Flt16Mat2D_scale( &matL, scaleA, scaleBbpA ); + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_create16( int16 xxA, int16 xyA, int16 yxA, int16 yyA, int16 bbpA ) +{ + struct bts_Flt16Mat2D matL; + matL.xxE = xxA; + matL.xyE = xyA; + matL.yxE = yxA; + matL.yyE = yyA; + matL.bbpE = bbpA; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_create32( int32 xxA, int32 xyA, int32 yxA, int32 yyA, int32 bbpA ) +{ + struct bts_Flt16Mat2D matL; + + if( ( xxA | xyA | yxA | yyA ) == 0 ) + { + matL.xxE = 0; + matL.xyE = 0; + matL.yxE = 0; + matL.yyE = 0; + matL.bbpE = 0; + } + else + { + int32 shiftL = bts_maxAbsIntLog2Of4( xxA, xyA, yxA, yyA ) - 13; + + if( shiftL > 0 ) + { + int32 sh1L = shiftL - 1; + matL.xxE = ( ( xxA >> sh1L ) + 1 ) >> 1; + matL.xyE = ( ( xyA >> sh1L ) + 1 ) >> 1; + matL.yxE = ( ( yxA >> sh1L ) + 1 ) >> 1; + matL.yyE = ( ( yyA >> sh1L ) + 1 ) >> 1; + } + else + { + matL.xxE = xxA << -shiftL; + matL.xyE = xyA << -shiftL; + matL.yxE = yxA << -shiftL; + matL.yyE = yyA << -shiftL; + } + + matL.bbpE = bbpA - shiftL; + } + + return matL; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat2D_scale( struct bts_Flt16Mat2D* ptrA, int32 scaleA, int32 scaleBbpA ) +{ + /* fit scale in 15 bit */ + uint32 scaleExpL = bts_absIntLog2( scaleA ); + if( scaleExpL > 14 ) + { + int32 shiftL = scaleExpL - 14; + scaleA = ( ( scaleA >> ( shiftL - 1 ) ) + 1 ) >> 1; + scaleBbpA -= shiftL; + } + + *ptrA = bts_Flt16Mat2D_create32( (int32)ptrA->xxE * scaleA, + (int32)ptrA->xyE * scaleA, + (int32)ptrA->yxE * scaleA, + (int32)ptrA->yyE * scaleA, + ptrA->bbpE + scaleBbpA ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Vec2D bts_Flt16Mat2D_map( const struct bts_Flt16Mat2D* matPtrA, + const struct bts_Int16Vec2D* vecPtrA ) +{ + struct bts_Int16Vec2D vecL; + + int32 xL = ( int32 ) matPtrA->xxE * vecPtrA->xE + ( int32 ) matPtrA->xyE * vecPtrA->yE; + int32 yL = ( int32 ) matPtrA->yxE * vecPtrA->xE + ( int32 ) matPtrA->yyE * vecPtrA->yE; + + if( matPtrA->bbpE > 0 ) + { + int32 sh1L = matPtrA->bbpE - 1; + vecL.xE = ( ( xL >> sh1L ) + 1 ) >> 1; + vecL.yE = ( ( yL >> sh1L ) + 1 ) >> 1; + } + else + { + /* not overflow safe */ + vecL.xE = xL << -matPtrA->bbpE; + vecL.yE = yL << -matPtrA->bbpE; + } + + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Mat2D_mapFlt( const struct bts_Flt16Mat2D* matPtrA, + const struct bts_Flt16Vec2D* vecPtrA ) +{ + int32 xL = ( int32 ) matPtrA->xxE * vecPtrA->xE + ( int32 ) matPtrA->xyE * vecPtrA->yE; + int32 yL = ( int32 ) matPtrA->yxE * vecPtrA->xE + ( int32 ) matPtrA->yyE * vecPtrA->yE; + int32 bbpL = matPtrA->bbpE + vecPtrA->bbpE; + return bts_Flt16Vec2D_create32( xL, yL, bbpL ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_mul( const struct bts_Flt16Mat2D* mat1PtrA, + const struct bts_Flt16Mat2D* mat2PtrA ) +{ + return bts_Flt16Mat2D_create32( ( int32 ) mat1PtrA->xxE * mat2PtrA->xxE + ( int32 ) mat1PtrA->xyE * mat2PtrA->yxE, + ( int32 ) mat1PtrA->xxE * mat2PtrA->xyE + ( int32 ) mat1PtrA->xyE * mat2PtrA->yyE, + ( int32 ) mat1PtrA->yxE * mat2PtrA->xxE + ( int32 ) mat1PtrA->yyE * mat2PtrA->yxE, + ( int32 ) mat1PtrA->yxE * mat2PtrA->xyE + ( int32 ) mat1PtrA->yyE * mat2PtrA->yyE, + mat1PtrA->bbpE + mat2PtrA->bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D* bts_Flt16Mat2D_mulTo( struct bts_Flt16Mat2D* mat1PtrA, + const struct bts_Flt16Mat2D* mat2PtrA ) +{ + *mat1PtrA = bts_Flt16Mat2D_mul( mat1PtrA, mat2PtrA ); + return mat1PtrA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat2D_invert( struct bts_Flt16Mat2D* ptrA ) +{ + int32 detL = ( int32 ) ptrA->xxE * ptrA->yyE - ( int32 ) ptrA->xyE * ptrA->yxE; + int32 detExpL = bbs_intLog2( detL ); + int32 dShrL = 0; + if( detExpL > 15 ) + { + dShrL = detExpL - 15; + detL = ( ( detL >> ( dShrL - 1 ) ) + 1 ) >> 1; + } + + if( detL == 0 ) + { + ptrA->xxE = ptrA->yyE = ptrA->xyE = ptrA->yxE = 0; + } + else + { + /* bbp: bbpE + 16 - ( bbpE * 2 - dShrL ) = 16 + dShrL - bbpE */ + int32 xxL = ( ( int32 )ptrA->xxE << 16 ) / detL; + int32 xyL = ( ( int32 )ptrA->xyE << 16 ) / detL; + int32 yxL = ( ( int32 )ptrA->yxE << 16 ) / detL; + int32 yyL = ( ( int32 )ptrA->yyE << 16 ) / detL; + *ptrA = bts_Flt16Mat2D_create32( xxL, -xyL, -yxL, yyL, 16 + dShrL - ptrA->bbpE ); + } +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat2D bts_Flt16Mat2D_inverted( const struct bts_Flt16Mat2D* ptrA ) +{ + struct bts_Flt16Mat2D matL = *ptrA; + bts_Flt16Mat2D_invert( &matL ); + return matL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Flt16Mat2D.h b/Embedded/common/src/b_TensorEm/Flt16Mat2D.h new file mode 100644 index 0000000..95e0a98 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Mat2D.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT16MAT2D_EM_H +#define bts_FLT16MAT2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" +#include "b_TensorEm/Int16Vec2D.h" +#include "b_TensorEm/Flt16Vec2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d matrix with floating point */ +struct bts_Flt16Mat2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** xx component */ + int16 xxE; + + /** xy component */ + int16 xyE; + + /** yx component */ + int16 yxE; + + /** yy component */ + int16 yyE; + + /** point position */ + int16 bbpE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes matrix */ +void bts_Flt16Mat2D_init( struct bts_Flt16Mat2D* ptrA ); + +/** destroys matrix */ +void bts_Flt16Mat2D_exit( struct bts_Flt16Mat2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_Flt16Mat2D_copy( struct bts_Flt16Mat2D* ptrA, const struct bts_Flt16Mat2D* srcPtrA ); + +/** equal operator */ +flag bts_Flt16Mat2D_equal( const struct bts_Flt16Mat2D* ptrA, const struct bts_Flt16Mat2D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** returns determinate of matrix; return bbp is ptrA->bbpE * 2 */ +uint32 bts_Flt16Mat2D_det( const struct bts_Flt16Mat2D* ptrA ); + +/** inverts matrix */ +void bts_Flt16Mat2D_invert( struct bts_Flt16Mat2D* ptrA ); + +/** returns inverted matrix */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_inverted( const struct bts_Flt16Mat2D* ptrA ); + +/** creates identity matrix */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_createIdentity( void ); + +/** creates rotation matrix */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_createRotation( phase16 angleA ); + +/** creates scale matrix */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_createScale( int32 scaleA, int32 scaleBbpA ); + +/** creates rigid matrix (scale & rotation) */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_createRigid( phase16 angleA, int32 scaleA, int32 scaleBbpA ); + +/** creates matrix from 16 bit values */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_create16( int16 xxA, int16 xyA, int16 yxA, int16 yyA, int16 bbpA ); + +/** creates matrix from 32 bit values (automatic adjustment of bbp value) */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_create32( int32 xxA, int32 xyA, int32 yxA, int32 yyA, int32 bbpA ); + +/** scales matrix by a factor */ +void bts_Flt16Mat2D_scale( struct bts_Flt16Mat2D* ptrA, int32 scaleA, int32 scaleBbpA ); + +/** multiplies matrix with vecA; returns resulting vector */ +struct bts_Int16Vec2D bts_Flt16Mat2D_map( const struct bts_Flt16Mat2D* matPtrA, + const struct bts_Int16Vec2D* vecPtrA ); + +/** Multiplies matrix with float vecA; returns resulting vector. */ +struct bts_Flt16Vec2D bts_Flt16Mat2D_mapFlt( const struct bts_Flt16Mat2D* matPtrA, + const struct bts_Flt16Vec2D* vecPtrA ); + +/** multiplies matrix with matA; returns resulting matrix */ +struct bts_Flt16Mat2D bts_Flt16Mat2D_mul( const struct bts_Flt16Mat2D* mat1PtrA, + const struct bts_Flt16Mat2D* mat2PtrA ); + +/** multiplies matrix with matA; returns pointer to resulting matrix */ +struct bts_Flt16Mat2D* bts_Flt16Mat2D_mulTo( struct bts_Flt16Mat2D* mat1PtrA, + const struct bts_Flt16Mat2D* mat2PtrA ); + +#endif /* bts_FLT16MAT2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Mat3D.c b/Embedded/common/src/b_TensorEm/Flt16Mat3D.c new file mode 100644 index 0000000..437632c --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Mat3D.c @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Mat3D.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat3D_init( struct bts_Flt16Mat3D* ptrA ) +{ + ptrA->bbpE = 0; + ptrA->xxE = 0; + ptrA->xyE = 0; + ptrA->xzE = 0; + ptrA->yxE = 0; + ptrA->yyE = 0; + ptrA->yzE = 0; + ptrA->zxE = 0; + ptrA->zyE = 0; + ptrA->zzE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat3D_exit( struct bts_Flt16Mat3D* ptrA ) +{ + ptrA->bbpE = 0; + ptrA->xxE = 0; + ptrA->xyE = 0; + ptrA->xzE = 0; + ptrA->yxE = 0; + ptrA->yyE = 0; + ptrA->yzE = 0; + ptrA->zxE = 0; + ptrA->zyE = 0; + ptrA->zzE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Mat3D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Mat3D *ptrA ) +{ + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Mat3D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Mat3D* ptrA, + uint16* memPtrA ) +{ + bbs_ERROR0( "not implemented" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Mat3D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Mat3D* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + bbs_ERROR0( "not implemented" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat3D bts_Flt16Mat3D_createIdentity() +{ + struct bts_Flt16Mat3D matL = { 1 << 14, 0, 0, 0, 1 << 14, 0, 0, 0, 1 << 14, 14 }; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat3D bts_Flt16Mat3D_createScale( int32 scaleA, int32 scaleBbpA ) +{ + struct bts_Flt16Mat3D matL = bts_Flt16Mat3D_createIdentity(); + bts_Flt16Mat3D_scale( &matL, scaleA, scaleBbpA ); + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat3D bts_Flt16Mat3D_create16( int16 xxA, int16 xyA, int16 xzA, + int16 yxA, int16 yyA, int16 yzA, + int16 zxA, int16 zyA, int16 zzA, + int16 bbpA ) +{ + struct bts_Flt16Mat3D matL; + matL.xxE = xxA; + matL.xyE = xyA; + matL.xzE = xzA; + matL.yxE = yxA; + matL.yyE = yyA; + matL.yzE = yzA; + matL.zxE = zxA; + matL.zyE = zyA; + matL.zzE = zzA; + matL.bbpE = bbpA; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat3D bts_Flt16Mat3D_create32( int32 xxA, int32 xyA, int32 xzA, + int32 yxA, int32 yyA, int32 yzA, + int32 zxA, int32 zyA, int32 zzA, + int32 bbpA ) +{ + struct bts_Flt16Mat3D matL; + + if( ( xxA | xyA | xzA | yxA | yyA | yzA | zxA | zyA | zzA ) == 0 ) + { + matL.xxE = 0; + matL.xyE = 0; + matL.xzE = 0; + matL.yxE = 0; + matL.yyE = 0; + matL.yzE = 0; + matL.zxE = 0; + matL.zyE = 0; + matL.zzE = 0; + matL.bbpE = 0; + } + else + { + int32 xShiftL = bts_maxAbsIntLog2Of3( xxA, xyA, xzA ) - 13; + int32 yShiftL = bts_maxAbsIntLog2Of3( yxA, yyA, yzA ) - 13; + int32 zShiftL = bts_maxAbsIntLog2Of3( zxA, zyA, zzA ) - 13; + + int32 shiftL = bbs_max( bbs_max( xShiftL, yShiftL ), zShiftL ); + + if( shiftL > 0 ) + { + int32 sh1L = shiftL - 1; + matL.xxE = ( ( xxA >> sh1L ) + 1 ) >> 1; + matL.xyE = ( ( xyA >> sh1L ) + 1 ) >> 1; + matL.xzE = ( ( xzA >> sh1L ) + 1 ) >> 1; + matL.yxE = ( ( yxA >> sh1L ) + 1 ) >> 1; + matL.yyE = ( ( yyA >> sh1L ) + 1 ) >> 1; + matL.yzE = ( ( yzA >> sh1L ) + 1 ) >> 1; + matL.zxE = ( ( zxA >> sh1L ) + 1 ) >> 1; + matL.zyE = ( ( zyA >> sh1L ) + 1 ) >> 1; + matL.zzE = ( ( zzA >> sh1L ) + 1 ) >> 1; + } + else + { + matL.xxE = xxA << -shiftL; + matL.xyE = xyA << -shiftL; + matL.xzE = xzA << -shiftL; + matL.yxE = yxA << -shiftL; + matL.yyE = yyA << -shiftL; + matL.yzE = yzA << -shiftL; + matL.zxE = zxA << -shiftL; + matL.zyE = zyA << -shiftL; + matL.zzE = zzA << -shiftL; + } + + matL.bbpE = bbpA - shiftL; + } + return matL; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Mat3D_scale( struct bts_Flt16Mat3D* ptrA, int32 scaleA, int32 scaleBbpA ) +{ + /* fit scale in 15 bit */ + uint32 scaleExpL = bts_absIntLog2( scaleA ); + if( scaleExpL > 14 ) + { + int32 shiftL = scaleExpL - 14; + scaleA = ( ( scaleA >> ( shiftL - 1 ) ) + 1 ) >> 1; + scaleBbpA -= shiftL; + } + + *ptrA = bts_Flt16Mat3D_create32( ptrA->xxE * scaleA, ptrA->xyE * scaleA, ptrA->xzE * scaleA, + ptrA->yxE * scaleA, ptrA->yyE * scaleA, ptrA->yzE * scaleA, + ptrA->zxE * scaleA, ptrA->zyE * scaleA, ptrA->zzE * scaleA, + ptrA->bbpE + scaleBbpA ); +} + +/* ------------------------------------------------------------------------- */ +#ifndef HW_EE /* causes internal compiler error in ee-gcc */ +struct bts_Int16Vec3D bts_Flt16Mat3D_map( const struct bts_Flt16Mat3D* matPtrA, + const struct bts_Int16Vec3D* vecPtrA ) +{ + struct bts_Int16Vec3D vecL; + + int32 xL = ( int32 ) matPtrA->xxE * vecPtrA->xE + ( int32 ) matPtrA->xyE * vecPtrA->yE + ( int32 ) matPtrA->xzE * vecPtrA->zE; + int32 yL = ( int32 ) matPtrA->yxE * vecPtrA->xE + ( int32 ) matPtrA->yyE * vecPtrA->yE + ( int32 ) matPtrA->yzE * vecPtrA->zE; + int32 zL = ( int32 ) matPtrA->zxE * vecPtrA->xE + ( int32 ) matPtrA->zyE * vecPtrA->yE + ( int32 ) matPtrA->zzE * vecPtrA->zE; + + if( matPtrA->bbpE > 0 ) + { + int32 sh1L = matPtrA->bbpE - 1; + vecL.xE = ( ( xL >> sh1L ) + 1 ) >> 1; + vecL.yE = ( ( yL >> sh1L ) + 1 ) >> 1; + vecL.zE = ( ( zL >> sh1L ) + 1 ) >> 1; + } + else + { + /* not overflow safe */ + vecL.xE = xL << -matPtrA->bbpE; + vecL.yE = yL << -matPtrA->bbpE; + vecL.zE = zL << -matPtrA->bbpE; + } + + return vecL; +} +#endif +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Mat3D_mapFlt( const struct bts_Flt16Mat3D* matPtrA, + const struct bts_Flt16Vec3D* vecPtrA ) +{ + /* avoids overflow summing intermediate products */ + int32 xL = ( ( ( ( int32 ) matPtrA->xxE * vecPtrA->xE + 1 ) >> 1 ) + + ( ( ( int32 ) matPtrA->xyE * vecPtrA->yE + 1 ) >> 1 ) + + ( ( ( int32 ) matPtrA->xzE * vecPtrA->zE + 1 ) >> 1 ) ); + + int32 yL = ( ( ( ( int32 ) matPtrA->yxE * vecPtrA->xE + 1 ) >> 1 ) + + ( ( ( int32 ) matPtrA->yyE * vecPtrA->yE + 1 ) >> 1 ) + + ( ( ( int32 ) matPtrA->yzE * vecPtrA->zE + 1 ) >> 1 ) ); + + int32 zL = ( ( ( ( int32 ) matPtrA->zxE * vecPtrA->xE + 1 ) >> 1 ) + + ( ( ( int32 ) matPtrA->zyE * vecPtrA->yE + 1 ) >> 1 ) + + ( ( ( int32 ) matPtrA->zzE * vecPtrA->zE + 1 ) >> 1 ) ); + + + return bts_Flt16Vec3D_create32( xL, yL, zL, vecPtrA->bbpE + matPtrA->bbpE - 1 ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat3D bts_Flt16Mat3D_mul( const struct bts_Flt16Mat3D* mat1PtrA, + const struct bts_Flt16Mat3D* mat2PtrA ) +{ + /* avoids overflow summing intermediate products */ + return bts_Flt16Mat3D_create32( + + ( ( ( int32 ) mat1PtrA->xxE * mat2PtrA->xxE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->xyE * mat2PtrA->yxE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->xzE * mat2PtrA->zxE + 1 ) >> 1 ), + ( ( ( int32 ) mat1PtrA->xxE * mat2PtrA->xyE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->xyE * mat2PtrA->yyE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->xzE * mat2PtrA->zyE + 1 ) >> 1 ), + ( ( ( int32 ) mat1PtrA->xxE * mat2PtrA->xzE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->xyE * mat2PtrA->yzE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->xzE * mat2PtrA->zzE + 1 ) >> 1 ), + + ( ( ( int32 ) mat1PtrA->yxE * mat2PtrA->xxE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->yyE * mat2PtrA->yxE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->yzE * mat2PtrA->zxE + 1 ) >> 1 ), + ( ( ( int32 ) mat1PtrA->yxE * mat2PtrA->xyE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->yyE * mat2PtrA->yyE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->yzE * mat2PtrA->zyE + 1 ) >> 1 ), + ( ( ( int32 ) mat1PtrA->yxE * mat2PtrA->xzE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->yyE * mat2PtrA->yzE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->yzE * mat2PtrA->zzE + 1 ) >> 1 ), + + ( ( ( int32 ) mat1PtrA->zxE * mat2PtrA->xxE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->zyE * mat2PtrA->yxE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->zzE * mat2PtrA->zxE + 1 ) >> 1 ), + ( ( ( int32 ) mat1PtrA->zxE * mat2PtrA->xyE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->zyE * mat2PtrA->yyE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->zzE * mat2PtrA->zyE + 1 ) >> 1 ), + ( ( ( int32 ) mat1PtrA->zxE * mat2PtrA->xzE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->zyE * mat2PtrA->yzE + 1 ) >> 1 ) + ( ( ( int32 ) mat1PtrA->zzE * mat2PtrA->zzE + 1 ) >> 1 ), + + mat1PtrA->bbpE + mat2PtrA->bbpE - 1 ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Mat3D* bts_Flt16Mat3D_mulTo( struct bts_Flt16Mat3D* mat1PtrA, + const struct bts_Flt16Mat3D* mat2PtrA ) +{ + *mat1PtrA = bts_Flt16Mat3D_mul( mat1PtrA, mat2PtrA ); + return mat1PtrA; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Mat3D.h b/Embedded/common/src/b_TensorEm/Flt16Mat3D.h new file mode 100644 index 0000000..740caa6 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Mat3D.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT16MAT3D_EM_H +#define bts_FLT16MAT3D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" +#include "b_TensorEm/Int16Vec3D.h" +#include "b_TensorEm/Flt16Vec3D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 3d matrix with floating point */ +struct bts_Flt16Mat3D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** xx component */ + int16 xxE; + + /** xy component */ + int16 xyE; + + /** xz component */ + int16 xzE; + + /** yx component */ + int16 yxE; + + /** yy component */ + int16 yyE; + + /** yz component */ + int16 yzE; + + /** zx component */ + int16 zxE; + + /** zy component */ + int16 zyE; + + /** zz component */ + int16 zzE; + + /** point position */ + int16 bbpE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes matrix */ +void bts_Flt16Mat3D_init( struct bts_Flt16Mat3D* ptrA ); + +/** destroys matrix */ +void bts_Flt16Mat3D_exit( struct bts_Flt16Mat3D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Flt16Mat3D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Mat3D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Flt16Mat3D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Mat3D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Flt16Mat3D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Mat3D* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creates identity matrix */ +struct bts_Flt16Mat3D bts_Flt16Mat3D_createIdentity( void ); + +/** creates scale matrix */ +struct bts_Flt16Mat3D bts_Flt16Mat3D_createScale( int32 scaleA, int32 scaleBbpA ); + +/** creates matrix from 16 bit values */ +struct bts_Flt16Mat3D bts_Flt16Mat3D_create16( int16 xxA, int16 xyA, int16 xzA, + int16 yxA, int16 yyA, int16 yzA, + int16 zxA, int16 zyA, int16 zzA, + int16 bbpA ); + +/** creates matrix from 32 bit values (automatic adjustment of bbp value) */ +struct bts_Flt16Mat3D bts_Flt16Mat3D_create32( int32 xxA, int32 xyA, int32 xzA, + int32 yxA, int32 yyA, int32 yzA, + int32 zxA, int32 zyA, int32 zzA, + int32 bbpA ); + +/** scales matrix by a factor */ +void bts_Flt16Mat3D_scale( struct bts_Flt16Mat3D* ptrA, int32 scaleA, int32 scaleBbpA ); + +/** multiplies matrix with vecA; returns resulting vector */ +#ifndef HW_EE /* causes internal compiler error in ee-gcc */ +struct bts_Int16Vec3D bts_Flt16Mat3D_map( const struct bts_Flt16Mat3D* matPtrA, + const struct bts_Int16Vec3D* vecPtrA ); +#endif +/** Multiplies matrix with float vecA; returns resulting vector. + * The point position of returned vector is the same as of the input vector. + */ +struct bts_Flt16Vec3D bts_Flt16Mat3D_mapFlt( const struct bts_Flt16Mat3D* matPtrA, + const struct bts_Flt16Vec3D* vecPtrA ); + +/** multiplies matrix with matA; returns resulting matrix */ +struct bts_Flt16Mat3D bts_Flt16Mat3D_mul( const struct bts_Flt16Mat3D* mat1PtrA, + const struct bts_Flt16Mat3D* mat2PtrA ); + +/** multiplies matrix with matA; returns pointer to resulting matrix */ +struct bts_Flt16Mat3D* bts_Flt16Mat3D_mulTo( struct bts_Flt16Mat3D* mat1PtrA, + const struct bts_Flt16Mat3D* mat2PtrA ); + +#endif /* bts_FLT16MAT3D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Vec.c b/Embedded/common/src/b_TensorEm/Flt16Vec.c new file mode 100644 index 0000000..6757dda --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Vec.c @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Vec.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_init( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA ) +{ + bbs_Int16Arr_init( cpA, &ptrA->arrE ); + ptrA->expE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_exit( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA ) +{ + bbs_Int16Arr_exit( cpA, &ptrA->arrE ); + ptrA->expE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_copy( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + const struct bts_Flt16Vec* srcPtrA ) +{ + bbs_Int16Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); + ptrA->expE = srcPtrA->expE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Flt16Vec_equal( struct bbs_Context* cpA, + const struct bts_Flt16Vec* ptrA, + const struct bts_Flt16Vec* srcPtrA ) +{ + if( !bbs_Int16Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ) ) return FALSE; + if( ptrA->expE != srcPtrA->expE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int16 bts_Flt16Vec_avg( struct bbs_Context* cpA, const struct bts_Flt16Vec* ptrA ) +{ + uint16 iL; + uint16 sizeL = ptrA->arrE.sizeE; + int32 sumL = 0; + const int16* srcL = ptrA->arrE.arrPtrE; + for( iL = 0; iL < sizeL; iL++ ) + { + sumL += srcL[ iL ]; + } + return sumL / ( int32 )sizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec_norm( struct bbs_Context* cpA, const struct bts_Flt16Vec* ptrA ) +{ + return bbs_vecNorm16( ptrA->arrE.arrPtrE, ptrA->arrE.sizeE ); +} + +/* ------------------------------------------------------------------------- */ + +uint16 bts_Flt16Vec_maxAbs( struct bbs_Context* cpA, const struct bts_Flt16Vec* ptrA ) +{ + uint16 iL; + uint16 sizeL = ptrA->arrE.sizeE; + uint16 maxL = 0; + const int16* srcL = ptrA->arrE.arrPtrE; + for( iL = 0; iL < sizeL; iL++ ) + { + uint16 vL = srcL[ iL ] > 0 ? srcL[ iL ] : -srcL[ iL ]; + maxL = vL > maxL ? vL : maxL; + } + return maxL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_create( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + bbs_Int16Arr_create( cpA, &ptrA->arrE, sizeA, mspA ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_size( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + uint32 sizeA ) +{ + bbs_Int16Arr_size( cpA, &ptrA->arrE, sizeA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Vec *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) /* mem size */ + + bbs_Int16Arr_memSize( cpA, &ptrA->arrE ) + + bbs_SIZEOF16( ptrA->expE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Vec* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Flt16Vec_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->expE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec_memRead( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + memPtrA += bbs_memRead16( &ptrA->expE, memPtrA ); + + if( memSizeL != bts_Flt16Vec_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Flt16Vec_memRead( const struct bts_Flt16Vec* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_maximizeMantisse( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ) +{ + uint32 maxAbsL = bts_Flt16Vec_maxAbs( cpA, ptrA ); + int16 shlL = 0; + + if( maxAbsL == 0 ) return; /* cannot maximize 0 */ + + while( maxAbsL < 0x4000 ) + { + shlL++; + maxAbsL <<= 1; + } + + if( shlL > 0 ) + { + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + int16* dstL = ptrA->arrE.arrPtrE; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] <<= shlL; + ptrA->expE -= shlL; + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec_maximizeAbsValue( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ) +{ + int32 maxAbsL = bts_Flt16Vec_maxAbs( cpA, ptrA ); + int32 fL; + if( maxAbsL == 0 ) return 0; /* vector is zero */ + + fL = ( int32 )0x7FFF0000 / maxAbsL; + + { + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + int16* dstL = ptrA->arrE.arrPtrE; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( ( int32 )dstL[ iL ] * fL + 32768 ) >> 16; + } + + return fL; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_zeroAverage( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ) +{ + uint16 iL; + uint16 sizeL = ptrA->arrE.sizeE; + int16* dstL = ptrA->arrE.arrPtrE; + int16 avgL = bts_Flt16Vec_avg( cpA, ptrA ); + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] -= avgL; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_normalize( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ) +{ + uint32 normL = bts_Flt16Vec_norm( cpA, ptrA ); + + if( normL == 0 ) + { + /* vector is zero - do nothing */ + return; + } + else + { + int16* dstL = ptrA->arrE.arrPtrE; + uint16 iL; + uint16 sizeL = ptrA->arrE.sizeE; + int16 expL = 0; + int32 fL; + + /* let norm occupy 17 bits */ + if( ( normL & 0xFFFE0000 ) != 0 ) + { + while( ( ( normL >> -expL ) & 0xFFFE0000 ) != 0 ) expL--; + normL >>= -expL; + } + else + { + while( ( ( normL << expL ) & 0xFFFF0000 ) == 0 ) expL++; + normL <<= expL; + } + + /* fL is positive and occupies only 16 bits - a product with int16 fits in int32 */ + fL = ( uint32 )0xFFFFFFFF / normL; + + /* multiply with factor */ + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( ( ( ( int32 )dstL[ iL ] * fL ) >> 15 ) + 1 ) >> 1; + + /* set exponent */ + ptrA->expE = expL - 16; + } +/* + { + uint32 testNormL = bts_Flt16Vec_norm( cpA, ptrA ); + printf( "test norm %f\n", ( float )testNormL / ( 1 << -ptrA->expE ) ); + } +*/ +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_setZero( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ) +{ + bbs_Int16Arr_fill( cpA, &ptrA->arrE, 0 ); + ptrA->expE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_mul( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA, int32 valA, int16 expA ) +{ + int32 valL = valA; + int16 expL = expA; + + if( valL == 0 ) + { + bts_Flt16Vec_setZero( cpA, ptrA ); + return; + } + else + { + uint32 iL; + uint32 sizeL = ptrA->arrE.sizeE; + int16* dstL = ptrA->arrE.arrPtrE; + + /* adjust valL to maximum 16 bit accuracy */ + uint32 absValL = valL > 0 ? valL : -valL; + if( ( absValL & 0xFFFF8000 ) != 0 ) + { + int32 shrL = 0; + while( ( absValL & 0xFFFF8000 ) != 0 ) + { + absValL >>= 1; + shrL++; + } + + if( shrL > 0 ) + { + valL = ( ( valL >> ( shrL - 1 ) ) + 1 ) >> 1; + expL += shrL; + if( valL >= 0x08000 ) valL = 0x07FFF; /* saturate */ + } + } + else + { + int32 shlL = 0; + while( ( absValL & 0xFFFFC000 ) == 0 ) + { + absValL <<= 1; + shlL++; + } + + valL <<= shlL; + expL -= shlL; + } + + for( iL = 0; iL < sizeL; iL++ ) + { + dstL[ iL ] = ( ( ( ( int32 )dstL[ iL ] * valL ) >> 15 ) + 1 ) >> 1; + } + ptrA->expE += expL + 16; + } +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_dotPtrd( struct bbs_Context* cpA, struct bts_Flt16Vec* vp1A, struct bts_Flt16Vec* vp2A, int32* manPtrA, int32* expPtrA ) +{ + bbs_DEF_fNameL( "void bts_Flt16Vec_dotPtrd( struct bbs_Context* cpA, struct bts_Flt16Vec* vp1A, struct bts_Flt16Vec* vp2A, int32* matPtrA, int32* expPtrA )" ) + uint16 iL; + uint16 sizeL = vp1A->arrE.sizeE; + const int16* arr1L = vp1A->arrE.arrPtrE; + const int16* arr2L = vp2A->arrE.arrPtrE; + int16 shrm1L = -1; /* shift minus 1 */ + int32 sumL; + + if( vp1A->arrE.sizeE != vp2A->arrE.sizeE ) + { + bbs_ERROR1( "%s:\nVectors have different size", fNameL ); + return; + } + + sumL = 0; + /* shrm1L == -1 */ + for( iL = 0; iL < sizeL; iL++ ) + { + sumL += ( int32 )arr1L[ iL ] * ( int32 )arr2L[ iL ]; + if( ( ( ( sumL > 0 ) ? sumL : -sumL ) & 0xC0000000 ) != 0 ) break; + } + + if( iL < sizeL ) + { + /* danger of overflow: increase shift; adjust sum */ + shrm1L++; + sumL = ( ( sumL >> 1 ) + 1 ) >> 1; + + /* shrm1L == 0 */ + for( iL = 0; iL < sizeL; iL++ ) + { + sumL += ( int32 )( ( arr1L[ iL ] + 1 ) >> 1 ) * ( int32 )( ( arr2L[ iL ] + 1 ) >> 1 ); + if( ( ( ( sumL > 0 ) ? sumL : -sumL ) & 0xC0000000 ) != 0 ) break; + } + + for( iL = 0; iL < sizeL; iL++ ) + { + if( ( ( ( sumL > 0 ) ? sumL : -sumL ) & 0xC0000000 ) != 0 ) + { + /* danger of overflow: increase shift; adjust sum */ + shrm1L++; + sumL = ( ( sumL >> 1 ) + 1 ) >> 1; + } + + sumL += ( int32 )( ( ( arr1L[ iL ] >> shrm1L ) + 1 ) >> 1 ) * ( int32 )( ( ( arr2L[ iL ] >> shrm1L ) + 1 ) >> 1 ); + } + } + + if( manPtrA != NULL ) *manPtrA = sumL; + if( expPtrA != NULL ) *expPtrA = vp1A->expE + vp2A->expE + ( ( shrm1L + 1 ) << 1 ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec_append( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA, struct bts_Flt16Vec* srcPtrA ) +{ + if( ptrA->arrE.sizeE == 0 ) + { + bts_Flt16Vec_copy( cpA, ptrA, srcPtrA ); + } + else + { + uint32 idxL = ptrA->arrE.sizeE; + bts_Flt16Vec_size( cpA, ptrA, idxL + srcPtrA->arrE.sizeE ); + + /* copy data */ + bbs_memcpy16( ptrA->arrE.arrPtrE + idxL, srcPtrA->arrE.arrPtrE, srcPtrA->arrE.sizeE ); + + /* equalize exponent */ + if( ptrA->expE > srcPtrA->expE ) + { + uint32 iL; + uint32 sizeL = srcPtrA->arrE.sizeE; + uint32 shrL = ptrA->expE - srcPtrA->expE; + int16* dstL = ptrA->arrE.arrPtrE + idxL; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( ( dstL[ iL ] >> ( shrL - 1 ) ) + 1 ) >> 1; + } + else if( ptrA->expE < srcPtrA->expE ) + { + uint32 iL; + uint32 sizeL = idxL; + uint32 shrL = srcPtrA->expE - ptrA->expE; + int16* dstL = ptrA->arrE.arrPtrE; + for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( ( dstL[ iL ] >> ( shrL - 1 ) ) + 1 ) >> 1; + ptrA->expE = srcPtrA->expE; + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Vec.h b/Embedded/common/src/b_TensorEm/Flt16Vec.h new file mode 100644 index 0000000..9c004f5 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Vec.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT_16_VEC_EM_H +#define bts_FLT_16_VEC_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/MemSeg.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_TensorEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** + * Vector with 16 bit components + * The vector operations are implemented with respect to maintain high accuracy and + * overflow safety for all possible vector configurations. + */ +struct bts_Flt16Vec +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** array of vector elements */ + struct bbs_Int16Arr arrE; + + /** exponent to elements */ + int16 expE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes vector */ +void bts_Flt16Vec_init( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA ); + +/** destroys vector */ +void bts_Flt16Vec_exit( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copies vector */ +void bts_Flt16Vec_copy( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + const struct bts_Flt16Vec* srcPtrA ); + +/** compares vector */ +flag bts_Flt16Vec_equal( struct bbs_Context* cpA, + const struct bts_Flt16Vec* ptrA, + const struct bts_Flt16Vec* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns average of vector without exponent */ +int16 bts_Flt16Vec_avg( struct bbs_Context* cpA, const struct bts_Flt16Vec* ptrA ); + +/** returns norm of vector without exponent */ +uint32 bts_Flt16Vec_norm( struct bbs_Context* cpA, const struct bts_Flt16Vec* ptrA ); + +/** returns maximum absulute value without exponent */ +uint16 bts_Flt16Vec_maxAbs( struct bbs_Context* cpA, const struct bts_Flt16Vec* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates vector */ +void bts_Flt16Vec_create( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** resize vector (sizeA must be smaller or equal to allocated size)*/ +void bts_Flt16Vec_size( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + uint32 sizeA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size in words (16-bit) object needs when written to memory */ +uint32 bts_Flt16Vec_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Vec* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_Flt16Vec_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Vec* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_Flt16Vec_memRead( struct bbs_Context* cpA, + struct bts_Flt16Vec* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** maximize mantisse values to reduce error propagation through multiple vector operations */ +void bts_Flt16Vec_maximizeMantisse( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ); + +/** scales vector such that max abs is as near as possible to 0x7FFF; returns scale factor used in format 16.16; returns 0 when vector is 0 */ +uint32 bts_Flt16Vec_maximizeAbsValue( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ); + +/** tranlates vector to zero average */ +void bts_Flt16Vec_zeroAverage( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ); + +/** normalizes vector (euclidean norm) */ +void bts_Flt16Vec_normalize( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ); + +/** sets vector to zero */ +void bts_Flt16Vec_setZero( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA ); + +/** multiplies a scalar to vector */ +void bts_Flt16Vec_mul( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA, int32 valA, int16 expA ); + +/** computes dot product; returns product as mantisse + exponent */ +void bts_Flt16Vec_dotPtrd( struct bbs_Context* cpA, struct bts_Flt16Vec* vp1A, struct bts_Flt16Vec* vp2A, int32* manPtrA, int32* expPtrA ); + +/** appends a vector */ +void bts_Flt16Vec_append( struct bbs_Context* cpA, struct bts_Flt16Vec* ptrA, struct bts_Flt16Vec* srcPtrA ); + +#endif /* bts_FLT_16_VEC_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Vec2D.c b/Embedded/common/src/b_TensorEm/Flt16Vec2D.c new file mode 100644 index 0000000..a65c621 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Vec2D.c @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Vec2D.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec2D_init( struct bts_Flt16Vec2D* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec2D_exit( struct bts_Flt16Vec2D* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec2D_copy( struct bts_Flt16Vec2D* ptrA, const struct bts_Flt16Vec2D* srcPtrA ) +{ + ptrA->bbpE = srcPtrA->bbpE; + ptrA->xE = srcPtrA->xE; + ptrA->yE = srcPtrA->yE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Flt16Vec2D_equal( const struct bts_Flt16Vec2D* ptrA, const struct bts_Flt16Vec2D* srcPtrA ) +{ + int32 bbpDiffL = ptrA->bbpE - srcPtrA->bbpE; + if( bbpDiffL == 0 ) + { + if( ptrA->xE != srcPtrA->xE ) return FALSE; + if( ptrA->yE != srcPtrA->yE ) return FALSE; + return TRUE; + } + + if( bbpDiffL > 0 ) + { + int32 xL = ( int32 ) srcPtrA->xE << bbpDiffL; + int32 yL = ( int32 ) srcPtrA->yE << bbpDiffL; + if( ptrA->xE != xL ) return FALSE; + if( ptrA->yE != yL ) return FALSE; + /* check if bits were lost by the shifting */ + if( srcPtrA->xE != ( xL >> bbpDiffL ) ) return FALSE; + if( srcPtrA->yE != ( yL >> bbpDiffL ) ) return FALSE; + return TRUE; + } + + if( bbpDiffL < 0 ) + { + int32 xL = ( int32 ) ptrA->xE << -bbpDiffL; + int32 yL = ( int32 ) ptrA->yE << -bbpDiffL; + if( xL != srcPtrA->xE ) return FALSE; + if( yL != srcPtrA->yE ) return FALSE; + /* check if bits were lost by the shifting */ + if( ptrA->xE != ( xL >> -bbpDiffL ) ) return FALSE; + if( ptrA->yE != ( yL >> -bbpDiffL ) ) return FALSE; + return TRUE; + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_create16( int16 xA, int16 yA, int16 bbpA ) +{ + struct bts_Flt16Vec2D vecL; + vecL.xE = xA; + vecL.yE = yA; + vecL.bbpE = bbpA; + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_createVec16( struct bts_Int16Vec2D vecA, int16 bbpA ) +{ + struct bts_Flt16Vec2D vecL; + vecL.xE = vecA.xE; + vecL.yE = vecA.yE; + vecL.bbpE = bbpA; + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_create32( int32 xA, int32 yA, int32 bbpA ) +{ + struct bts_Flt16Vec2D vecL; + if( ( xA | yA ) == 0 ) + { + vecL.xE = 0; + vecL.yE = 0; + vecL.bbpE = 0; + } + else + { + int32 shiftL = bts_maxAbsIntLog2Of2( xA, yA ) - 13; + + if( shiftL > 0 ) + { + int32 sh1L = shiftL - 1; + vecL.xE = ( ( xA >> sh1L ) + 1 ) >> 1; + vecL.yE = ( ( yA >> sh1L ) + 1 ) >> 1; + } + else + { + vecL.xE = xA << -shiftL; + vecL.yE = yA << -shiftL; + } + vecL.bbpE = bbpA - shiftL; + } + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +int32 bts_Flt16Vec2D_dotPrd( const struct bts_Flt16Vec2D* vec1PtrA, + const struct bts_Flt16Vec2D* vec2PtrA ) +{ + return ( int32 ) vec1PtrA->xE * vec2PtrA->xE + ( int32 ) vec1PtrA->yE * vec2PtrA->yE; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec2D_norm2( const struct bts_Flt16Vec2D* ptrA ) +{ + return ( int32 ) ptrA->xE * ptrA->xE + ( int32 ) ptrA->yE * ptrA->yE; +} + +/* ------------------------------------------------------------------------- */ + +uint16 bts_Flt16Vec2D_norm( const struct bts_Flt16Vec2D* ptrA ) +{ + return bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + ( int32 ) ptrA->yE * ptrA->yE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec2D_normalize( struct bts_Flt16Vec2D* ptrA ) +{ + int32 normL = bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + ( int32 ) ptrA->yE * ptrA->yE ); + int32 xL = ( ( int32 ) ptrA->xE << 16 ) / normL; + int32 yL = ( ( int32 ) ptrA->yE << 16 ) / normL; + *ptrA = bts_Flt16Vec2D_create32( xL, yL, 16 ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_normalized( const struct bts_Flt16Vec2D* ptrA ) +{ + struct bts_Flt16Vec2D vecL = *ptrA; + bts_Flt16Vec2D_normalize( &vecL ); + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +phase16 bts_Flt16Vec2D_angle( const struct bts_Flt16Vec2D* vecPtrA ) +{ + return bbs_phase16( vecPtrA->xE, vecPtrA->yE ); +} + +/* ------------------------------------------------------------------------- */ + +phase16 bts_Flt16Vec2D_enclosedAngle( const struct bts_Flt16Vec2D* vec1PtrA, + const struct bts_Flt16Vec2D* vec2PtrA ) +{ + int32 xL = ( int32 ) vec1PtrA->xE * vec2PtrA->xE + ( int32 ) vec1PtrA->yE * vec2PtrA->yE; + int32 yL = ( int32 ) vec1PtrA->yE * vec2PtrA->xE - ( int32 ) vec1PtrA->xE * vec2PtrA->yE; + return bbs_phase16( xL, yL ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_add( struct bts_Flt16Vec2D vec1A, struct bts_Flt16Vec2D vec2A ) +{ + int32 xL, yL, bbpL; + int32 shiftL = vec1A.bbpE - vec2A.bbpE; + + if( shiftL > 0 ) + { + xL = ( ( int32 ) vec2A.xE << shiftL ) + vec1A.xE; + yL = ( ( int32 ) vec2A.yE << shiftL ) + vec1A.yE; + bbpL = vec1A.bbpE; + } + else + { + xL = ( ( int32 ) vec1A.xE << -shiftL ) + vec2A.xE; + yL = ( ( int32 ) vec1A.yE << -shiftL ) + vec2A.yE; + bbpL = vec2A.bbpE; + } + + return bts_Flt16Vec2D_create32( xL, yL, bbpL ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_sub( struct bts_Flt16Vec2D vec1A, struct bts_Flt16Vec2D vec2A ) +{ + int32 xL, yL, bbpL; + int32 shiftL = vec1A.bbpE - vec2A.bbpE; + + if( shiftL > 0 ) + { + xL = ( int32 ) vec1A.xE - ( ( int32 ) vec2A.xE << shiftL ); + yL = ( int32 ) vec1A.yE - ( ( int32 ) vec2A.yE << shiftL ); + bbpL = vec1A.bbpE; + } + else + { + xL = ( ( int32 ) vec1A.xE << -shiftL ) - vec2A.xE; + yL = ( ( int32 ) vec1A.yE << -shiftL ) - vec2A.yE; + bbpL = vec2A.bbpE; + } + + return bts_Flt16Vec2D_create32( xL, yL, bbpL ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_Flt16Vec2D_mul( struct bts_Flt16Vec2D vecA, int16 factorA, int32 bbpFactorA ) +{ + int32 xL = ( int32 ) vecA.xE * factorA; + int32 yL = ( int32 ) vecA.yE * factorA; + return bts_Flt16Vec2D_create32( xL, yL, bbpFactorA + vecA.bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Vec2D bts_Flt16Vec2D_int16Vec2D( struct bts_Flt16Vec2D vecA, int32 dstBbpA ) +{ + struct bts_Int16Vec2D vecL; + int32 shiftL = vecA.bbpE - dstBbpA; + + if( shiftL > 0 ) + { + vecL.xE = ( ( vecA.xE >> ( shiftL - 1 ) ) + 1 ) >> 1; + vecL.yE = ( ( vecA.yE >> ( shiftL - 1 ) ) + 1 ) >> 1; + } + else + { + vecL.xE = vecA.xE << ( -shiftL ); + vecL.yE = vecA.yE << ( -shiftL ); + } + + return vecL; +} + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Flt16Vec2D.h b/Embedded/common/src/b_TensorEm/Flt16Vec2D.h new file mode 100644 index 0000000..ce6828c --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Vec2D.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT16VEC2D_EM_H +#define bts_FLT16VEC2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" +#include "b_TensorEm/Int16Vec2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d vector with floating point */ +struct bts_Flt16Vec2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** x component */ + int16 xE; + + /** y component */ + int16 yE; + + /** point position */ + int16 bbpE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes vector */ +void bts_Flt16Vec2D_init( struct bts_Flt16Vec2D* ptrA ); + +/** destroys vector */ +void bts_Flt16Vec2D_exit( struct bts_Flt16Vec2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_Flt16Vec2D_copy( struct bts_Flt16Vec2D* ptrA, const struct bts_Flt16Vec2D* srcPtrA ); + +/** equal operator */ +flag bts_Flt16Vec2D_equal( const struct bts_Flt16Vec2D* ptrA, const struct bts_Flt16Vec2D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creates vector from 16 bit values */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_create16( int16 xA, int16 yA, int16 bbpA ); + +/** creates vector from 16 bit vactor */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_createVec16( struct bts_Int16Vec2D vecA, int16 bbpA ); + +/** creates vector from 32 bit values (automatic adjustment of bbp value) */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_create32( int32 xA, int32 yA, int32 bbpA ); + + +/** dot product of vectors; return bbp is vec1PtrA->bbpE + vec2PtrA->bbpE */ +int32 bts_Flt16Vec2D_dotPrd( const struct bts_Flt16Vec2D* vec1PtrA, + const struct bts_Flt16Vec2D* vec2PtrA ); + +/** returns square norm of vector; return bbp is ptrA->bbpE * 2 */ +uint32 bts_Flt16Vec2D_norm2( const struct bts_Flt16Vec2D* ptrA ); + +/** returns norm of vector; return bbp is ptrA->bbpE*/ +uint16 bts_Flt16Vec2D_norm( const struct bts_Flt16Vec2D* ptrA ); + +/** normalizes vector; bbpA defines number of bits behind the point */ +void bts_Flt16Vec2D_normalize( struct bts_Flt16Vec2D* ptrA ); + +/** returns normalized vector; bbpA defines number of bits behind the point */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_normalized( const struct bts_Flt16Vec2D* ptrA ); + +/** computes angle between vector and x axis*/ +phase16 bts_Flt16Vec2D_angle( const struct bts_Flt16Vec2D* vecPtrA ); + +/** computes angle between two vectors */ +phase16 bts_Flt16Vec2D_enclosedAngle( const struct bts_Flt16Vec2D* vec1PtrA, + const struct bts_Flt16Vec2D* vec2PtrA ); + +/** adds two vectors; returns resulting vector */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_add( struct bts_Flt16Vec2D vec1A, struct bts_Flt16Vec2D vec2A ); + +/** subtracts vec1A - vec2A; returns resulting vector */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_sub( struct bts_Flt16Vec2D vec1A, struct bts_Flt16Vec2D vec2A ); + +/** multiplies vecor with scalar; returns resulting vector */ +struct bts_Flt16Vec2D bts_Flt16Vec2D_mul( struct bts_Flt16Vec2D vecA, int16 factorA, int32 bbpFactorA ); + +/** converts vecA into bts_Int16Vec2D */ +struct bts_Int16Vec2D bts_Flt16Vec2D_int16Vec2D( struct bts_Flt16Vec2D vecA, int32 dstBbpA ); + +#endif /* bts_FLT16VEC2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Vec3D.c b/Embedded/common/src/b_TensorEm/Flt16Vec3D.c new file mode 100644 index 0000000..032fc20 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Vec3D.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Flt16Vec3D.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec3D_init( struct bts_Flt16Vec3D* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->zE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec3D_exit( struct bts_Flt16Vec3D* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; + ptrA->zE = 0; + ptrA->bbpE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +flag bts_Flt16Vec3D_equal( const struct bts_Flt16Vec3D* ptrA, const struct bts_Flt16Vec3D* srcPtrA ) +{ + int32 bbpDiffL = ptrA->bbpE - srcPtrA->bbpE; + if( bbpDiffL == 0 ) + { + if( ptrA->xE != srcPtrA->xE ) return FALSE; + if( ptrA->yE != srcPtrA->yE ) return FALSE; + if( ptrA->zE != srcPtrA->zE ) return FALSE; + return TRUE; + } + + if( bbpDiffL > 0 ) + { + int32 xL = ( int32 ) srcPtrA->xE << bbpDiffL; + int32 yL = ( int32 ) srcPtrA->yE << bbpDiffL; + int32 zL = ( int32 ) srcPtrA->zE << bbpDiffL; + if( ptrA->xE != xL ) return FALSE; + if( ptrA->yE != yL ) return FALSE; + if( ptrA->zE != zL ) return FALSE; + return TRUE; + } + + if( bbpDiffL < 0 ) + { + int32 xL = ( int32 ) ptrA->xE << -bbpDiffL; + int32 yL = ( int32 ) ptrA->yE << -bbpDiffL; + int32 zL = ( int32 ) ptrA->zE << -bbpDiffL; + if( xL != srcPtrA->xE ) return FALSE; + if( yL != srcPtrA->yE ) return FALSE; + if( zL != srcPtrA->zE ) return FALSE; + return TRUE; + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec3D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Vec3D *ptrA ) +{ + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec3D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Vec3D* ptrA, + uint16* memPtrA ) +{ + bbs_ERROR0( "not implemented" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec3D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Vec3D* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + bbs_ERROR0( "not implemented" ); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Vec3D_create16( int16 xA, int16 yA, int16 zA, int16 bbpA ) +{ + struct bts_Flt16Vec3D vecL; + vecL.xE = xA; + vecL.yE = yA; + vecL.zE = zA; + vecL.bbpE = bbpA; + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Vec3D_create32( int32 xA, int32 yA, int32 zA, int32 bbpA ) +{ + struct bts_Flt16Vec3D vecL; + if( ( xA | yA | zA ) == 0 ) + { + vecL.xE = 0; + vecL.yE = 0; + vecL.zE = 0; + vecL.bbpE = 0; + } + else + { + int32 shiftL = bts_maxAbsIntLog2Of3( xA, yA, zA ) - 13; + + if( shiftL > 0 ) + { + int32 sh1L = shiftL - 1; + vecL.xE = ( ( xA >> sh1L ) + 1 ) >> 1; + vecL.yE = ( ( yA >> sh1L ) + 1 ) >> 1; + vecL.zE = ( ( zA >> sh1L ) + 1 ) >> 1; + } + else + { + vecL.xE = xA << -shiftL; + vecL.yE = yA << -shiftL; + vecL.zE = zA << -shiftL; + } + vecL.bbpE = bbpA - shiftL; + } + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Flt16Vec3D_norm2( const struct bts_Flt16Vec3D* ptrA ) +{ + return ( int32 ) ptrA->xE * ptrA->xE + + ( int32 ) ptrA->yE * ptrA->yE + + ( int32 ) ptrA->zE * ptrA->zE; +} + +/* ------------------------------------------------------------------------- */ + +uint16 bts_Flt16Vec3D_norm( const struct bts_Flt16Vec3D* ptrA ) +{ + return bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + + ( int32 ) ptrA->yE * ptrA->yE + + ( int32 ) ptrA->zE * ptrA->zE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Flt16Vec3D_normalize( struct bts_Flt16Vec3D* ptrA ) +{ + int32 normL = bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + + ( int32 ) ptrA->yE * ptrA->yE + + ( int32 ) ptrA->zE * ptrA->zE ); + + int32 xL = ( ( int32 ) ptrA->xE << 16 ) / normL; + int32 yL = ( ( int32 ) ptrA->yE << 16 ) / normL; + int32 zL = ( ( int32 ) ptrA->zE << 16 ) / normL; + *ptrA = bts_Flt16Vec3D_create32( xL, yL, zL, 16 ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Vec3D_normalized( const struct bts_Flt16Vec3D* ptrA ) +{ + struct bts_Flt16Vec3D vecL = *ptrA; + bts_Flt16Vec3D_normalize( &vecL ); + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Vec3D_add( struct bts_Flt16Vec3D vec1A, struct bts_Flt16Vec3D vec2A ) +{ + int32 xL, yL, zL, bbpL; + int32 shiftL = vec1A.bbpE - vec2A.bbpE; + + if( shiftL > 0 ) + { + xL = vec1A.xE + ( ( int32 ) vec2A.xE << shiftL ); + yL = vec1A.yE + ( ( int32 ) vec2A.yE << shiftL ); + zL = vec1A.zE + ( ( int32 ) vec2A.zE << shiftL ); + bbpL = vec1A.bbpE; + } + else + { + xL = ( ( int32 ) vec1A.xE << -shiftL ) + vec2A.xE; + yL = ( ( int32 ) vec1A.yE << -shiftL ) + vec2A.yE; + zL = ( ( int32 ) vec1A.zE << -shiftL ) + vec2A.zE; + bbpL = vec2A.bbpE; + } + + return bts_Flt16Vec3D_create32( xL, yL, zL, bbpL ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Vec3D_sub( struct bts_Flt16Vec3D vec1A, struct bts_Flt16Vec3D vec2A ) +{ + int32 xL, yL, zL, bbpL; + int32 shiftL = vec1A.bbpE - vec2A.bbpE; + + if( shiftL > 0 ) + { + xL = vec1A.xE - ( ( int32 ) vec2A.xE << shiftL ); + yL = vec1A.yE - ( ( int32 ) vec2A.yE << shiftL ); + zL = vec1A.zE - ( ( int32 ) vec2A.zE << shiftL ); + bbpL = vec1A.bbpE; + } + else + { + xL = ( ( int32 ) vec1A.xE << -shiftL ) - vec2A.xE; + yL = ( ( int32 ) vec1A.yE << -shiftL ) - vec2A.yE; + zL = ( ( int32 ) vec1A.zE << -shiftL ) - vec2A.zE; + bbpL = vec2A.bbpE; + } + + return bts_Flt16Vec3D_create32( xL, yL, zL, bbpL ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec3D bts_Flt16Vec3D_mul( struct bts_Flt16Vec3D vecA, int16 factorA, int32 bbpFactorA ) +{ + int32 xL = ( int32 ) vecA.xE * factorA; + int32 yL = ( int32 ) vecA.yE * factorA; + int32 zL = ( int32 ) vecA.zE * factorA; + return bts_Flt16Vec3D_create32( xL, yL, zL, bbpFactorA + vecA.bbpE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Flt16Vec3D.h b/Embedded/common/src/b_TensorEm/Flt16Vec3D.h new file mode 100644 index 0000000..eab1714 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Flt16Vec3D.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FLT16VEC3D_EM_H +#define bts_FLT16VEC3D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 3d vector with floating point */ +struct bts_Flt16Vec3D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** x component */ + int16 xE; + + /** y component */ + int16 yE; + + /** z component */ + int16 zE; + + /** point position */ + int16 bbpE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes vector */ +void bts_Flt16Vec3D_init( struct bts_Flt16Vec3D* ptrA ); + +/** destroys vector */ +void bts_Flt16Vec3D_exit( struct bts_Flt16Vec3D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** equal operator */ +flag bts_Flt16Vec3D_equal( const struct bts_Flt16Vec3D* ptrA, const struct bts_Flt16Vec3D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Flt16Vec3D_memSize( struct bbs_Context* cpA, + const struct bts_Flt16Vec3D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Flt16Vec3D_memWrite( struct bbs_Context* cpA, + const struct bts_Flt16Vec3D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Flt16Vec3D_memRead( struct bbs_Context* cpA, + struct bts_Flt16Vec3D* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creates vector from 16 bit values */ +struct bts_Flt16Vec3D bts_Flt16Vec3D_create16( int16 xA, int16 yA, int16 zA, int16 bbpA ); + +/** creates vector from 32 bit values (automatic adjustment of bbp value) */ +struct bts_Flt16Vec3D bts_Flt16Vec3D_create32( int32 xA, int32 yA, int32 zA, int32 bbpA ); + +/** returns square norm of vector; return bbp is ptrA->bbpE * 2 */ +uint32 bts_Flt16Vec3D_norm2( const struct bts_Flt16Vec3D* ptrA ); + +/** returns norm of vector; return bbp is ptrA->bbpE*/ +uint16 bts_Flt16Vec3D_norm( const struct bts_Flt16Vec3D* ptrA ); + +/** normalizes vector; bbpA defines number of bits behind the point */ +void bts_Flt16Vec3D_normalize( struct bts_Flt16Vec3D* ptrA ); + +/** returns normalized vector; bbpA defines number of bits behind the point */ +struct bts_Flt16Vec3D bts_Flt16Vec3D_normalized( const struct bts_Flt16Vec3D* ptrA ); + +/** adds two vectors; returns resulting vector */ +struct bts_Flt16Vec3D bts_Flt16Vec3D_add( struct bts_Flt16Vec3D vec1A, struct bts_Flt16Vec3D vec2A ); + +/** subtracts vec1A - vec2A; returns resulting vector */ +struct bts_Flt16Vec3D bts_Flt16Vec3D_sub( struct bts_Flt16Vec3D vec1A, struct bts_Flt16Vec3D vec2A ); + +/** multiplies vecor with scalar; returns resulting vector */ +struct bts_Flt16Vec3D bts_Flt16Vec3D_mul( struct bts_Flt16Vec3D vecA, int16 factorA, int32 bbpFactorA ); + +#endif /* bts_FLT16VEC3D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Functions.c b/Embedded/common/src/b_TensorEm/Functions.c new file mode 100644 index 0000000..ae9f3ae --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Functions.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ external functions } ----------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_absIntLog2( int32 vA ) +{ + return bbs_intLog2( bbs_abs( vA ) ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_maxAbsIntLog2Of2( int32 v1A, int32 v2A ) +{ + uint32 maxL = bbs_max( ( uint32 )bbs_abs( v1A ), ( uint32 )bbs_abs( v2A ) ); + return bbs_intLog2( maxL ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_maxAbsIntLog2Of3( int32 v1A, int32 v2A, int32 v3A ) +{ + uint32 maxL = bbs_abs( v1A ); + maxL = bbs_max( maxL, ( uint32 )bbs_abs( v2A ) ); + maxL = bbs_max( maxL, ( uint32 )bbs_abs( v3A ) ); + return bbs_intLog2( maxL ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_maxAbsIntLog2Of4( int32 v1A, int32 v2A, int32 v3A, int32 v4A ) +{ + uint32 maxL = bbs_abs( v1A ); + maxL = bbs_max( maxL, ( uint32 )bbs_abs( v2A ) ); + maxL = bbs_max( maxL, ( uint32 )bbs_abs( v3A ) ); + maxL = bbs_max( maxL, ( uint32 )bbs_abs( v4A ) ); + return bbs_intLog2( maxL ); +} + +/* ------------------------------------------------------------------------- */ diff --git a/Embedded/common/src/b_TensorEm/Functions.h b/Embedded/common/src/b_TensorEm/Functions.h new file mode 100644 index 0000000..8cc9533 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Functions.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_FUNCTIONS_EM_H +#define bts_FUNCTIONS_EM_H + +/** + * This file contains general purpose functions. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +enum bts_AltType +{ + bts_ALT_IDENTITY = 1, /* identity transformation */ + bts_ALT_TRANS, /* restricted to translation only */ + bts_ALT_TRANS_SCALE, /* restricted to translation and scale only */ + bts_ALT_RIGID, /* restricted to rigid transformation (translation + scale + rotation) */ + bts_ALT_LINEAR, /* allows all degrees of freedom for affine linear transformation */ + bts_ALT_TRANS_SCALE_XYZ /* restricted to translation and scaling in x,y,z directions */ +}; + +enum bts_RBFType +{ + bts_RBF_IDENTITY = 1, /* no rbf deformation */ + bts_RBF_LINEAR /* linear, i.e. ||r|| */ +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/** compute the integer logarithm of the absolute value */ +uint32 bts_absIntLog2( int32 vA ); + +/** compute the integer logarithm of the maximal absolute value of all arguments */ +uint32 bts_maxAbsIntLog2Of2( int32 v1A, int32 v2A ); + +/** compute the integer logarithm of the maximal absolute value of all arguments */ +uint32 bts_maxAbsIntLog2Of3( int32 v1A, int32 v2A, int32 v3A ); + +/** compute the integer logarithm of the maximal absolute value of all arguments */ +uint32 bts_maxAbsIntLog2Of4( int32 v1A, int32 v2A, int32 v3A, int32 v4A ); + +#endif /* bts_FUNCTIONS_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/IdCluster2D.c b/Embedded/common/src/b_TensorEm/IdCluster2D.c new file mode 100644 index 0000000..d04344c --- /dev/null +++ b/Embedded/common/src/b_TensorEm/IdCluster2D.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Math.h" +#include "b_TensorEm/IdCluster2D.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_init( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA ) +{ + bts_Cluster2D_init( cpA, &ptrA->clusterE ); + bbs_Int16Arr_init( cpA, &ptrA->idArrE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_exit( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA ) +{ + bts_Cluster2D_exit( cpA, &ptrA->clusterE ); + bbs_Int16Arr_exit( cpA, &ptrA->idArrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_copy( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + const struct bts_IdCluster2D* srcPtrA ) +{ + bts_Cluster2D_copy( cpA, &ptrA->clusterE, &srcPtrA->clusterE ); + bbs_Int16Arr_copy( cpA, &ptrA->idArrE, &srcPtrA->idArrE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_IdCluster2D_equal( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA, + const struct bts_IdCluster2D* srcPtrA ) +{ + if( !bts_Cluster2D_equal( cpA, &ptrA->clusterE, &srcPtrA->clusterE ) ) return FALSE; + if( !bbs_Int16Arr_equal( cpA, &ptrA->idArrE, &srcPtrA->idArrE ) ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Vec2D bts_IdCluster2D_center( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA ) +{ + return bts_Cluster2D_center( cpA, &ptrA->clusterE ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Rect bts_IdCluster2D_boundingBox( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA ) +{ + return bts_Cluster2D_boundingBox( cpA, &ptrA->clusterE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_create( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + bts_Cluster2D_create( cpA, &ptrA->clusterE, sizeA, mspA ); + bbs_Int16Arr_create( cpA, &ptrA->idArrE, sizeA, mspA ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_size( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + uint32 sizeA ) +{ + bts_Cluster2D_size( cpA, &ptrA->clusterE, sizeA ); + bbs_Int16Arr_size( cpA, &ptrA->idArrE, sizeA ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_transform( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + struct bts_Flt16Alt2D altA ) +{ + bts_Cluster2D_transform( cpA, &ptrA->clusterE, altA ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_copyTransform( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + const struct bts_IdCluster2D* srcPtrA, + struct bts_Flt16Alt2D altA, + uint32 dstBbpA ) +{ + bts_Cluster2D_copyTransform( cpA, &ptrA->clusterE, &srcPtrA->clusterE, altA, dstBbpA ); + bbs_Int16Arr_copy( cpA, &ptrA->idArrE, &srcPtrA->idArrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_IdCluster2D_memSize( struct bbs_Context* cpA, + const struct bts_IdCluster2D *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bts_Cluster2D_memSize( cpA, &ptrA->clusterE ) + + bbs_Int16Arr_memSize( cpA, &ptrA->idArrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_IdCluster2D_memWrite( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_IdCluster2D_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_ID_CLUSTER2D_VERSION, memPtrA ); + memPtrA += bts_Cluster2D_memWrite( cpA, &ptrA->clusterE, memPtrA ); + memPtrA += bbs_Int16Arr_memWrite( cpA, &ptrA->idArrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_IdCluster2D_memRead( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL; + uint32 versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_ID_CLUSTER2D_VERSION, memPtrA ); + memPtrA += bts_Cluster2D_memRead( cpA, &ptrA->clusterE, memPtrA, mspA ); + memPtrA += bbs_Int16Arr_memRead( cpA, &ptrA->idArrE, memPtrA, mspA ); + if( memSizeL != bts_IdCluster2D_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_IdCluster2D_memRead( const struct bts_IdCluster2D* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_IdCluster2D_convertToEqivalentClusters( struct bbs_Context* cpA, + const struct bts_IdCluster2D* inCluster1PtrA, + const struct bts_IdCluster2D* inCluster2PtrA, + struct bts_Cluster2D* outCluster1PtrA, + struct bts_Cluster2D* outCluster2PtrA ) +{ + uint32 iL, jL; + uint32 countL = 0; + + uint32 size1L = inCluster1PtrA->clusterE.sizeE; + uint32 size2L = inCluster2PtrA->clusterE.sizeE; + + const int16* idArr1L = inCluster1PtrA->idArrE.arrPtrE; + const int16* idArr2L = inCluster2PtrA->idArrE.arrPtrE; + + const struct bts_Int16Vec2D* srcVecArr1E = inCluster1PtrA->clusterE.vecArrE; + const struct bts_Int16Vec2D* srcVecArr2E = inCluster2PtrA->clusterE.vecArrE; + + struct bts_Int16Vec2D* dstVecArr1E = outCluster1PtrA->vecArrE; + struct bts_Int16Vec2D* dstVecArr2E = outCluster2PtrA->vecArrE; + + uint32 maxOutSizeL = bbs_min( outCluster1PtrA->allocatedSizeE, outCluster2PtrA->allocatedSizeE ); + bts_Cluster2D_size( cpA, outCluster1PtrA, maxOutSizeL ); + bts_Cluster2D_size( cpA, outCluster2PtrA, maxOutSizeL ); + + for( iL = 0; iL < size1L; iL++ ) + { + int32 idL = idArr1L[ iL ]; + if( idL >= 0 ) + { + for( jL = 0; jL < size2L; jL++ ) + { + if( idL == idArr2L[ jL ] ) break; + } + + if( jL < size2L ) + { + if( countL == maxOutSizeL ) + { + bbs_ERROR0( "void bts_IdCluster2D_convertToEqivalentClusters( .... ):\n" + "Destination clusters are insufficiently allocated" ); + return; + } + + dstVecArr1E[ countL ] = srcVecArr1E[ iL ]; + dstVecArr2E[ countL ] = srcVecArr2E[ jL ]; + countL++; + } + } + } + + bts_Cluster2D_size( cpA, outCluster1PtrA, countL ); + bts_Cluster2D_size( cpA, outCluster2PtrA, countL ); + + outCluster1PtrA->bbpE = inCluster1PtrA->clusterE.bbpE; + outCluster2PtrA->bbpE = inCluster2PtrA->clusterE.bbpE; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Flt16Alt2D bts_IdCluster2D_alt( struct bbs_Context* cpA, + const struct bts_IdCluster2D* srcPtrA, + struct bts_IdCluster2D* dstPtrA, + enum bts_AltType altTypeA, + struct bts_Cluster2D* tmpPtr1A, /* temporary cluster 1 */ + struct bts_Cluster2D* tmpPtr2A ) /* temporary cluster 2 */ +{ + bts_IdCluster2D_convertToEqivalentClusters( cpA, srcPtrA, dstPtrA, tmpPtr1A, tmpPtr2A ); + return bts_Cluster2D_alt( cpA, tmpPtr1A, tmpPtr2A, altTypeA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/IdCluster2D.h b/Embedded/common/src/b_TensorEm/IdCluster2D.h new file mode 100644 index 0000000..e76ce21 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/IdCluster2D.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_ID_CLUSTER2D_EM_H +#define bts_ID_CLUSTER2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_TensorEm/Cluster2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bts_ID_CLUSTER2D_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** 2d vector array with node id information */ +struct bts_IdCluster2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /* vector array */ + struct bts_Cluster2D clusterE; + + /** array of id numbers */ + struct bbs_Int16Arr idArrE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes cluster */ +void bts_IdCluster2D_init( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA ); + +/** destroys cluster */ +void bts_IdCluster2D_exit( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copies cluster */ +void bts_IdCluster2D_copy( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + const struct bts_IdCluster2D* srcPtrA ); + +/** compares cluster */ +flag bts_IdCluster2D_equal( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA, + const struct bts_IdCluster2D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/** returns center of gravity */ +struct bts_Flt16Vec2D bts_IdCluster2D_center( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA ); + +/** returns bounding box */ +struct bts_Int16Rect bts_IdCluster2D_boundingBox( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA ); + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates cluster */ +void bts_IdCluster2D_create( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** resize cluster (sizeA must be smaller or equal to allocated size)*/ +void bts_IdCluster2D_size( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + uint32 sizeA ); + +/** transforms cluster according to alt (function does not change bbp of cluster) */ +void bts_IdCluster2D_transform( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + struct bts_Flt16Alt2D altA ); + +/** copies src cluster and simultaneously transforms vectors according to alt using dstBbpA as resulting cluster format */ +void bts_IdCluster2D_copyTransform( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + const struct bts_IdCluster2D* srcPtrA, + struct bts_Flt16Alt2D altA, + uint32 dstBbpA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_IdCluster2D_memSize( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_IdCluster2D_memWrite( struct bbs_Context* cpA, + const struct bts_IdCluster2D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_IdCluster2D_memRead( struct bbs_Context* cpA, + struct bts_IdCluster2D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/* This function extracts equivalent 2d sub clusters which positions + * correponts to those nodes that have a non-negative id occurring + * in both input clusters. + * Note: Nodes with negative ids are ignored + * Non-Negative ids must not occur twice in one cluster. + */ +void bts_IdCluster2D_convertToEqivalentClusters( struct bbs_Context* cpA, + const struct bts_IdCluster2D* inCluster1PtrA, + const struct bts_IdCluster2D* inCluster2PtrA, + struct bts_Cluster2D* outCluster1PtrA, + struct bts_Cluster2D* outCluster2PtrA ); + +/** Computes the best affine linear transformation from *srcPtrA to *dstPtrA using matching id values. + * Constrains of trafo are given by altTypeA + * + * This function selects and matches nodes with corresponsing non-negative id values of source + * an destination clusters. Nodes with negative id values are ignored. Id values >= 0 must be unique + * per node. + */ +struct bts_Flt16Alt2D bts_IdCluster2D_alt( struct bbs_Context* cpA, + const struct bts_IdCluster2D* srcPtrA, + struct bts_IdCluster2D* dstPtrA, + enum bts_AltType altTypeA, + struct bts_Cluster2D* tmpPtr1A, /* temporary cluster 1 */ + struct bts_Cluster2D* tmpPtr2A ); /* temporary cluster 2 */ + + +#endif /* bts_ID_CLUSTER2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Int16Mat2D.c b/Embedded/common/src/b_TensorEm/Int16Mat2D.c new file mode 100644 index 0000000..af5e12d --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Mat2D.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Int16Mat2D.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Mat2D bts_Int16Mat2D_createIdentity() +{ + struct bts_Int16Mat2D matL = { 1 << 14, 0, 0, 1 << 14, 14 }; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Mat2D bts_Int16Mat2D_createRotation( phase16 angleA ) +{ + int16 cL = bbs_cos16( angleA ); + int16 sL = bbs_sin16( angleA ); + struct bts_Int16Mat2D matL; + matL.xxE = cL; + matL.xyE = -sL; + matL.yxE = sL; + matL.yyE = cL; + matL.bbpE = 14; + return matL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Mat2D bts_Int16Mat2D_createRigid( phase16 angleA, struct flt16 scaleA ) +{ + struct bts_Int16Mat2D matL = bts_Int16Mat2D_createRotation( angleA ); + bts_Int16Mat2D_scale( &matL, scaleA ); + return matL; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Int16Mat2D_scale( struct bts_Int16Mat2D* ptrA, struct flt16 scaleA ) +{ + int32 xxL = ( int32 ) ptrA->xxE * scaleA.valE; + int32 xyL = ( int32 ) ptrA->xyE * scaleA.valE; + int32 yxL = ( int32 ) ptrA->yxE * scaleA.valE; + int32 yyL = ( int32 ) ptrA->yyE * scaleA.valE; + + uint32 shiftL = bts_maxAbsIntLog2Of4( xxL, xyL, yxL, yyL ) - 15; + + ptrA->xxE = xxL >> shiftL; + ptrA->xyE = xyL >> shiftL; + ptrA->yxE = yxL >> shiftL; + ptrA->yyE = yyL >> shiftL; + + ptrA->bbpE += scaleA.bbpE - shiftL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Vec2D bts_Int16Mat2D_map( const struct bts_Int16Mat2D* matPtrA, + const struct bts_Int16Vec2D* vecPtrA ) +{ + struct bts_Int16Vec2D vecL; + vecL.xE = ( ( int32 ) matPtrA->xxE * vecPtrA->xE + ( int32 ) matPtrA->xyE * vecPtrA->yE ) >> matPtrA->bbpE; + vecL.yE = ( ( int32 ) matPtrA->yxE * vecPtrA->xE + ( int32 ) matPtrA->yyE * vecPtrA->yE ) >> matPtrA->bbpE; + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Mat2D bts_Int16Mat2D_mul( const struct bts_Int16Mat2D* mat1PtrA, + const struct bts_Int16Mat2D* mat2PtrA ) +{ + struct bts_Int16Mat2D matL; + int32 xxL = ( int32 ) mat1PtrA->xxE * mat2PtrA->xxE + ( int32 ) mat1PtrA->xyE * mat2PtrA->yxE; + int32 xyL = ( int32 ) mat1PtrA->xxE * mat2PtrA->xyE + ( int32 ) mat1PtrA->xyE * mat2PtrA->yyE; + int32 yxL = ( int32 ) mat1PtrA->yxE * mat2PtrA->xxE + ( int32 ) mat1PtrA->yyE * mat2PtrA->yxE; + int32 yyL = ( int32 ) mat1PtrA->yxE * mat2PtrA->xyE + ( int32 ) mat1PtrA->yyE * mat2PtrA->yyE; + + uint32 shiftL = bts_maxAbsIntLog2Of4( xxL, xyL, yxL, yyL ) - 15; + + matL.xxE = xxL >> shiftL; + matL.xyE = xyL >> shiftL; + matL.yxE = yxL >> shiftL; + matL.yyE = yyL >> shiftL; + + matL.bbpE = mat1PtrA->bbpE + mat2PtrA->bbpE - shiftL; + + return matL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Int16Mat2D.h b/Embedded/common/src/b_TensorEm/Int16Mat2D.h new file mode 100644 index 0000000..d07fb5f --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Mat2D.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_INT16MAT2D_EM_H +#define bts_INT16MAT2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" +#include "b_TensorEm/Int16Vec2D.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d matrix */ +struct bts_Int16Mat2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** xx component */ + int16 xxE; + + /** xy component */ + int16 xyE; + + /** yx component */ + int16 yxE; + + /** yy component */ + int16 yyE; + + /** fixed point position */ + int16 bbpE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** creates identity matrix */ +struct bts_Int16Mat2D bts_Int16Mat2D_createIdentity( void ); + +/** creates rotation matrix */ +struct bts_Int16Mat2D bts_Int16Mat2D_createRotation( phase16 angleA ); + +/** creates rigid matrix (scale & rotation) */ +struct bts_Int16Mat2D bts_Int16Mat2D_createRigid( phase16 angleA, struct flt16 scaleA ); + +/** scales matrix by a factor */ +void bts_Int16Mat2D_scale( struct bts_Int16Mat2D* ptrA, struct flt16 scaleA ); + +/** multiplies matrix with vecA; returns resulting vector */ +struct bts_Int16Vec2D bts_Int16Mat2D_map( const struct bts_Int16Mat2D* matPtrA, + const struct bts_Int16Vec2D* vecPtrA ); + +/** multiplies matrix with matA; returns resulting matrix */ +struct bts_Int16Mat2D bts_Int16Mat2D_mul( const struct bts_Int16Mat2D* mat1PtrA, + const struct bts_Int16Mat2D* mat2PtrA ); + +#endif /* bts_INT16MAT2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Int16Rect.c b/Embedded/common/src/b_TensorEm/Int16Rect.c new file mode 100644 index 0000000..2d5824e --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Rect.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Int16Rect.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Int16Rect_init( struct bbs_Context* cpA, struct bts_Int16Rect* ptrA ) +{ + ptrA->x1E = 0; + ptrA->y1E = 0; + ptrA->x2E = 0; + ptrA->y2E = 0; +} + +void bts_Int16Rect_exit( struct bbs_Context* cpA, struct bts_Int16Rect* ptrA ) +{ + ptrA->x1E = 0; + ptrA->y1E = 0; + ptrA->x2E = 0; + ptrA->y2E = 0; +} + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Rect bts_Int16Rect_create( int16 x1A, int16 y1A, int16 x2A, int16 y2A ) +{ + struct bts_Int16Rect rectL; + rectL.x1E = x1A; + rectL.y1E = y1A; + rectL.x2E = x2A; + rectL.y2E = y2A; + return rectL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Rect_memSize( struct bbs_Context* cpA, + const struct bts_Int16Rect *ptrA ) +{ + return bbs_SIZEOF16( struct bts_Int16Rect ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Rect_memWrite( struct bbs_Context* cpA, + const struct bts_Int16Rect* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite16( &ptrA->x1E, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->y1E, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->x2E, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->y2E, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Rect_memRead( struct bbs_Context* cpA, + struct bts_Int16Rect* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead16( &ptrA->x1E, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->y1E, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->x2E, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->y2E, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Int16Rect.h b/Embedded/common/src/b_TensorEm/Int16Rect.h new file mode 100644 index 0000000..be37407 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Rect.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_INT16RECT_EM_H +#define bts_INT16RECT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d vector */ +struct bts_Int16Rect +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** upper left component */ + int16 x1E; + + /** upper left component */ + int16 y1E; + + /** lower right component */ + int16 x2E; + + /** lower right component */ + int16 y2E; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes rectangle */ +void bts_Int16Rect_init( struct bbs_Context* cpA, struct bts_Int16Rect* ptrA ); + +/** destroys rectangle */ +void bts_Int16Rect_exit( struct bbs_Context* cpA, struct bts_Int16Rect* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** initialize rectangle */ +struct bts_Int16Rect bts_Int16Rect_create( int16 x1A, int16 y1A, int16 x2A, int16 y2A ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Int16Rect_memSize( struct bbs_Context* cpA, + const struct bts_Int16Rect* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Int16Rect_memWrite( struct bbs_Context* cpA, + const struct bts_Int16Rect* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Int16Rect_memRead( struct bbs_Context* cpA, + struct bts_Int16Rect* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + + +#endif /* bts_INT16RECT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Int16Vec2D.c b/Embedded/common/src/b_TensorEm/Int16Vec2D.c new file mode 100644 index 0000000..198ed0f --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Vec2D.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Int16Vec2D.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Int16Vec2D_init( struct bts_Int16Vec2D* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Int16Vec2D_exit( struct bts_Int16Vec2D* ptrA ) +{ + ptrA->xE = 0; + ptrA->yE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec2D_memSize( struct bbs_Context* cpA, + const struct bts_Int16Vec2D *ptrA ) +{ + return bbs_SIZEOF16( struct bts_Int16Vec2D ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec2D_memWrite( struct bbs_Context* cpA, + const struct bts_Int16Vec2D* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite16( &ptrA->xE, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->yE, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec2D_memRead( struct bbs_Context* cpA, + struct bts_Int16Vec2D* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead16( &ptrA->xE, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->yE, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +int32 bts_Int16Vec2D_dotPrd( const struct bts_Int16Vec2D* vec1PtrA, + const struct bts_Int16Vec2D* vec2PtrA ) +{ + return ( int32 ) vec1PtrA->xE * vec2PtrA->xE + ( int32 ) vec1PtrA->yE * vec2PtrA->yE; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec2D_norm2( const struct bts_Int16Vec2D* ptrA ) +{ + return ( int32 ) ptrA->xE * ptrA->xE + ( int32 ) ptrA->yE * ptrA->yE; +} + +/* ------------------------------------------------------------------------- */ + +uint16 bts_Int16Vec2D_norm( const struct bts_Int16Vec2D* ptrA ) +{ + return bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + ( int32 ) ptrA->yE * ptrA->yE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Int16Vec2D_normalize( struct bts_Int16Vec2D* ptrA, int32 bbpA ) +{ + int32 normL = bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + ( int32 ) ptrA->yE * ptrA->yE ); + int32 xL = ( ( int32 ) ptrA->xE << 16 ) / normL; + int32 yL = ( ( int32 ) ptrA->yE << 16 ) / normL; + ptrA->xE = xL >> ( 16 - bbpA ); + ptrA->yE = yL >> ( 16 - bbpA ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Vec2D bts_Int16Vec2D_normalized( const struct bts_Int16Vec2D* ptrA, int32 bbpA ) +{ + struct bts_Int16Vec2D vecL = *ptrA; + bts_Int16Vec2D_normalize( &vecL, bbpA ); + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +phase16 bts_Int16Vec2D_angle( const struct bts_Int16Vec2D* vecPtrA ) +{ + return bbs_phase16( vecPtrA->xE, vecPtrA->yE ); +} + +/* ------------------------------------------------------------------------- */ + +phase16 bts_Int16Vec2D_enclosedAngle( const struct bts_Int16Vec2D* vec1PtrA, + const struct bts_Int16Vec2D* vec2PtrA ) +{ + int32 xL = ( int32 ) vec1PtrA->xE * vec2PtrA->xE + ( int32 ) vec1PtrA->yE * vec2PtrA->yE; + int32 yL = ( int32 ) vec1PtrA->yE * vec2PtrA->xE - ( int32 ) vec1PtrA->xE * vec2PtrA->yE; + return bbs_phase16( xL, yL ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Int16Vec2D.h b/Embedded/common/src/b_TensorEm/Int16Vec2D.h new file mode 100644 index 0000000..3f0a4e0 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Vec2D.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_INT16VEC2D_EM_H +#define bts_INT16VEC2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Phase.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d vector */ +struct bts_Int16Vec2D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** x component */ + int16 xE; + + /** y component */ + int16 yE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes vector */ +void bts_Int16Vec2D_init( struct bts_Int16Vec2D* ptrA ); + +/** destroys vector */ +void bts_Int16Vec2D_exit( struct bts_Int16Vec2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Int16Vec2D_memSize( struct bbs_Context* cpA, + const struct bts_Int16Vec2D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Int16Vec2D_memWrite( struct bbs_Context* cpA, + const struct bts_Int16Vec2D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Int16Vec2D_memRead( struct bbs_Context* cpA, + struct bts_Int16Vec2D* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** dot product of vectors */ +int32 bts_Int16Vec2D_dotPrd( const struct bts_Int16Vec2D* vec1PtrA, + const struct bts_Int16Vec2D* vec2PtrA ); + +/** returns square norm of vector */ +uint32 bts_Int16Vec2D_norm2( const struct bts_Int16Vec2D* ptrA ); + +/** returns norm of vector */ +uint16 bts_Int16Vec2D_norm( const struct bts_Int16Vec2D* ptrA ); + +/** normalizes vector; bbpA defines number of bits behind the point */ +void bts_Int16Vec2D_normalize( struct bts_Int16Vec2D* ptrA, int32 bbpA ); + +/** returns normalized vector; bbpA defines number of bits behind the point */ +struct bts_Int16Vec2D bts_Int16Vec2D_normalized( const struct bts_Int16Vec2D* ptrA, int32 bbpA ); + +/** computes angle between vector and x axis*/ +phase16 bts_Int16Vec2D_angle( const struct bts_Int16Vec2D* vecPtrA ); + +/** computes angle between two vectors */ +phase16 bts_Int16Vec2D_enclosedAngle( const struct bts_Int16Vec2D* vec1PtrA, + const struct bts_Int16Vec2D* vec2PtrA ); + +#endif /* bts_INT16VEC2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Int16Vec3D.c b/Embedded/common/src/b_TensorEm/Int16Vec3D.c new file mode 100644 index 0000000..587a6cc --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Vec3D.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Int16Vec3D.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec3D_memSize( struct bbs_Context* cpA, + const struct bts_Int16Vec3D *ptrA ) +{ + return bbs_SIZEOF16( struct bts_Int16Vec3D ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec3D_memWrite( struct bbs_Context* cpA, + const struct bts_Int16Vec3D* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite16( &ptrA->xE, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->yE, memPtrA ); + memPtrA += bbs_memWrite16( &ptrA->zE, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec3D_memRead( struct bbs_Context* cpA, + struct bts_Int16Vec3D* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead16( &ptrA->xE, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->yE, memPtrA ); + memPtrA += bbs_memRead16( &ptrA->zE, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int16Vec3D_norm2( const struct bts_Int16Vec3D* ptrA ) +{ + return ( int32 ) ptrA->xE * ptrA->xE + + ( int32 ) ptrA->yE * ptrA->yE + + ( int32 ) ptrA->zE * ptrA->zE; +} + +/* ------------------------------------------------------------------------- */ + +uint16 bts_Int16Vec3D_norm( const struct bts_Int16Vec3D* ptrA ) +{ + return bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + + ( int32 ) ptrA->yE * ptrA->yE + + ( int32 ) ptrA->zE * ptrA->zE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Int16Vec3D_normalize( struct bts_Int16Vec3D* ptrA, int32 bbpA ) +{ + int32 normL = bbs_sqrt32( ( int32 ) ptrA->xE * ptrA->xE + + ( int32 ) ptrA->yE * ptrA->yE + + ( int32 ) ptrA->zE * ptrA->zE ); + + int32 xL = ( ( int32 )ptrA->xE << 16 ) / normL; + int32 yL = ( ( int32 )ptrA->yE << 16 ) / normL; + int32 zL = ( ( int32 )ptrA->zE << 16 ) / normL; + ptrA->xE = xL >> ( 16 - bbpA ); + ptrA->yE = yL >> ( 16 - bbpA ); + ptrA->zE = zL >> ( 16 - bbpA ); +} + +/* ------------------------------------------------------------------------- */ + +struct bts_Int16Vec3D bts_Int16Vec3D_normalized( const struct bts_Int16Vec3D* ptrA, int32 bbpA ) +{ + struct bts_Int16Vec3D vecL = *ptrA; + bts_Int16Vec3D_normalize( &vecL, bbpA ); + return vecL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Int16Vec3D.h b/Embedded/common/src/b_TensorEm/Int16Vec3D.h new file mode 100644 index 0000000..943bff6 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int16Vec3D.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_INT16VEC3D_EM_H +#define bts_INT16VEC3D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 3d vector */ +struct bts_Int16Vec3D +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** x component */ + int16 xE; + + /** y component */ + int16 yE; + + /** z component */ + int16 zE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Int16Vec3D_memSize( struct bbs_Context* cpA, + const struct bts_Int16Vec3D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Int16Vec3D_memWrite( struct bbs_Context* cpA, + const struct bts_Int16Vec3D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Int16Vec3D_memRead( struct bbs_Context* cpA, + struct bts_Int16Vec3D* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** returns square norm of vector */ +uint32 bts_Int16Vec3D_norm2( const struct bts_Int16Vec3D* ptrA ); + +/** returns norm of vector */ +uint16 bts_Int16Vec3D_norm( const struct bts_Int16Vec3D* ptrA ); + +/** normalizes vector; bbpA defines number of bits behind the point */ +void bts_Int16Vec3D_normalize( struct bts_Int16Vec3D* ptrA, int32 bbpA ); + +/** returns normalized vector; bbpA defines number of bits behind the point */ +struct bts_Int16Vec3D bts_Int16Vec3D_normalized( const struct bts_Int16Vec3D* ptrA, int32 bbpA ); + +#endif /* bts_INT16VEC3D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Int32Mat.c b/Embedded/common/src/b_TensorEm/Int32Mat.c new file mode 100644 index 0000000..768fd97 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int32Mat.c @@ -0,0 +1,490 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Int32Mat.h" +#include "b_TensorEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Int32Mat_reduceToNBits( int32* ptrA, uint32 sizeA, int32* bbpPtrA, uint32 nBitsA ) +{ + int32 shiftL; + + /* find max element */ + int32 maxL = 0; + int32* ptrL = ptrA; + int32 iL = sizeA; + while( iL-- ) + { + int32 xL = *ptrL++; + if( xL < 0 ) xL = -xL; + if( xL > maxL ) maxL = xL; + } + + /* determine shift */ + shiftL = bts_absIntLog2( maxL ) + 1 - nBitsA; + + if( shiftL > 0 ) + { + ptrL = ptrA; + iL = sizeA; + while( iL-- ) + { + *ptrL = ( ( *ptrL >> ( shiftL - 1 ) ) + 1 ) >> 1; + ptrL++; + } + + *bbpPtrA -= shiftL; + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Int32Mat_init( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA ) +{ + ptrA->widthE = 0; + bbs_Int32Arr_init( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Int32Mat_exit( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA ) +{ + ptrA->widthE = 0; + bbs_Int32Arr_exit( cpA, &ptrA->arrE ); +} +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Int32Mat_create( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA, + int32 widthA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + bbs_Int32Arr_create( cpA, &ptrA->arrE, widthA * widthA, mspA ); + ptrA->widthE = widthA; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Int32Mat_copy( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA, + const struct bts_Int32Mat* srcPtrA ) +{ + if( ptrA->widthE != srcPtrA->widthE ) + { + bbs_ERROR0( "void bts_Int32Mat_copy( struct bts_Int32Mat* ptrA, struct bts_Int32Mat* srcPtrA ):\n" + "size mismatch" ); + return; + } + + bbs_Int32Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int32Mat_memSize( struct bbs_Context* cpA, + const struct bts_Int32Mat *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->widthE ) + + bbs_Int32Arr_memSize( cpA, &ptrA->arrE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int32Mat_memWrite( struct bbs_Context* cpA, + const struct bts_Int32Mat* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Int32Mat_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_INT32MAT_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_Int32Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Int32Mat_memRead( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_INT32MAT_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->widthE, memPtrA ); + memPtrA += bbs_Int32Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); + + if( memSizeL != bts_Int32Mat_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Int32Mat_memRead( const struct bts_Int32Mat* ptrA, const void* memPtrA ):\n" + "size mismatch" ); + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +flag bts_Int32Mat_solve( struct bbs_Context* cpA, + const int32* matA, + int32 matWidthA, + const int32* inVecA, + int32* outVecA, + int32 bbpA, + int32* tmpMatA, + int32* tmpVecA ) +{ + bbs_memcpy32( tmpMatA, matA, ( matWidthA * matWidthA ) * bbs_SIZEOF32( int32 ) ); + + return bts_Int32Mat_solve2( cpA, + tmpMatA, + matWidthA, + inVecA, + outVecA, + bbpA, + tmpVecA ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Int32Mat_solve2( struct bbs_Context* cpA, + int32* matA, + int32 matWidthA, + const int32* inVecA, + int32* outVecA, + int32 bbpA, + int32* tmpVecA ) +{ + int32 sizeL = matWidthA; + int32 bbpL = bbpA; + int32 iL, jL, kL; + int32 iPivL; + int32 jPivL; + + int32* vecL = outVecA; + int32* matL = matA; + int32* checkArrL = tmpVecA; + + for( iL = 0; iL < sizeL; iL++ ) + { + checkArrL[ iL ] = 0; + } + + bbs_memcpy32( outVecA, inVecA, sizeL * bbs_SIZEOF32( int32 ) ); + + iPivL = 0; + + for( kL = 0; kL < sizeL; kL++ ) + { + /* find pivot */ + int32 maxAbsL = 0; + int32* pivRowL; + + int32 bbp_pivRowL, bbp_vecL, shiftL; + + jPivL = -1; + for( iL = 0; iL < sizeL; iL++ ) + { + if( checkArrL[ iL ] != 1 ) + { + int32* rowL = matL + ( iL * sizeL ); + for( jL = 0; jL < sizeL; jL++ ) + { + if( checkArrL[ jL ] == 0 ) + { + int32 absElemL = rowL[ jL ]; + if( absElemL < 0 ) absElemL = -absElemL; + if( maxAbsL < absElemL ) + { + maxAbsL = absElemL; + iPivL = iL; + jPivL = jL; + } + } + else if( checkArrL[ jL ] > 1 ) + { + return FALSE; + } + } + } + } + + /* successfull ? */ + if( jPivL < 0 ) + { + return FALSE; + } + + checkArrL[ jPivL ]++; + + /* exchange rows to put pivot on diagonal, if neccessary */ + if( iPivL != jPivL ) + { + int32* row1PtrL = matL + ( iPivL * sizeL ); + int32* row2PtrL = matL + ( jPivL * sizeL ); + for( jL = 0; jL < sizeL; jL++ ) + { + int32 tmpL = *row1PtrL; + *row1PtrL++ = *row2PtrL; + *row2PtrL++ = tmpL; + } + + { + int32 tmpL = vecL[ jPivL ]; + vecL[ jPivL ] = vecL[ iPivL ]; + vecL[ iPivL ] = tmpL; + } + } + /* now index jPivL specifies pivot row and maximum element */ + + + /** Overflow protection: only if the highest bit of the largest matrix element is set, + * we need to shift the whole matrix and the right side vector 1 bit to the right, + * to make sure there can be no overflow when the pivot row gets subtracted from the + * other rows. + * Getting that close to overflow is a rare event, so this shift will happen only + * occasionally, or not at all. + */ + if( maxAbsL & 1073741824 ) /*( 1 << 30 )*/ + { + /* right shift matrix by 1 */ + int32 iL = sizeL * sizeL; + int32* ptrL = matL; + while( iL-- ) + { + *ptrL = ( *ptrL + 1 ) >> 1; + ptrL++; + } + + /* right shift right side vector by 1 */ + iL = sizeL; + ptrL = vecL; + while( iL-- ) + { + *ptrL = ( *ptrL + 1 ) >> 1; + ptrL++; + } + + /* decrement bbpL */ + bbpL--; + } + + + /* reduce elements of pivot row to 15 bit */ + pivRowL = matL + jPivL * sizeL; + bbp_pivRowL = bbpL; + bts_Int32Mat_reduceToNBits( pivRowL, sizeL, &bbp_pivRowL, 15 ); + + /* scale pivot row such that maximum equals 1 */ + { + int32 maxL = pivRowL[ jPivL ]; + int32 bbp_maxL = bbp_pivRowL; + int32 factorL = 1073741824 / maxL; /*( 1 << 30 )*/ + + for( jL = 0; jL < sizeL; jL++ ) + { + pivRowL[ jL ] = ( pivRowL[ jL ] * factorL + ( 1 << 14 ) ) >> 15; + } + bbp_pivRowL = 15; + + /* set to 1 to avoid computational errors */ + pivRowL[ jPivL ] = ( int32 )1 << bbp_pivRowL; + + shiftL = 30 - bts_absIntLog2( vecL[ jPivL ] ); + + vecL[ jPivL ] = ( vecL[ jPivL ] << shiftL ) / maxL; + bbp_vecL = bbpL + shiftL - bbp_maxL; + + bbs_int32ReduceToNBits( &( vecL[ jPivL ] ), &bbp_vecL, 15 ); + } + + /* subtract pivot row from all other rows */ + for( iL = 0; iL < sizeL; iL++ ) + { + if( iL != jPivL ) + { + int32* rowPtrL = matL + iL * sizeL; + + int32 tmpL = *( rowPtrL + jPivL ); + int32 bbp_tmpL = bbpL; + bbs_int32ReduceToNBits( &tmpL, &bbp_tmpL, 15 ); + + shiftL = bbp_tmpL + bbp_pivRowL - bbpL; + if( shiftL > 0 ) + { + for( jL = 0; jL < sizeL; jL++ ) + { + *rowPtrL++ -= ( ( ( tmpL * pivRowL[ jL ] ) >> ( shiftL - 1 ) ) + 1 ) >> 1; + } + } + else + { + for( jL = 0; jL < sizeL; jL++ ) + { + *rowPtrL++ -= ( tmpL * pivRowL[ jL ] ) << -shiftL; + } + } + + shiftL = bbp_tmpL + bbp_vecL - bbpL; + if( shiftL > 0 ) + { + vecL[ iL ] -= ( ( ( tmpL * vecL[ jPivL ] ) >> ( shiftL - 1 ) ) + 1 ) >> 1; + } + else + { + vecL[ iL ] -= ( tmpL * vecL[ jPivL ] ) << -shiftL; + } + } + } + + /* change bbp of pivot row back to bbpL */ + shiftL = bbpL - bbp_pivRowL; + if( shiftL >= 0 ) + { + for( jL = 0; jL < sizeL; jL++ ) + { + pivRowL[ jL ] <<= shiftL; + } + } + else + { + shiftL = -shiftL; + for( jL = 0; jL < sizeL; jL++ ) + { + pivRowL[ jL ] = ( ( pivRowL[ jL ] >> ( shiftL - 1 ) ) + 1 ) >> 1; + } + } + + shiftL = bbpL - bbp_vecL; + if( shiftL >= 0 ) + { + vecL[ jPivL ] <<= shiftL; + } + else + { + shiftL = -shiftL; + vecL[ jPivL ] = ( ( vecL[ jPivL ] >> ( shiftL - 1 ) ) + 1 ) >> 1; + } +/* +if( sizeL <= 5 ) bts_Int32Mat_print( matL, vecL, sizeL, bbpL ); +*/ + } /* of kL */ + + /* in case bbpL has been decreased by the overflow protection, change it back now */ + if( bbpA > bbpL ) + { + /* find largest element of solution vector */ + int32 maxL = 0; + int32 iL, shiftL; + for( iL = 0; iL < sizeL; iL++ ) + { + int32 xL = vecL[ iL ]; + if( xL < 0 ) xL = -xL; + if( xL > maxL ) maxL = xL; + } + + /* check whether we can left shift without overflow */ + shiftL = 30 - bts_absIntLog2( maxL ); + if( shiftL < ( bbpA - bbpL ) ) + { + /* + bbs_WARNING1( "flag bts_Int32Mat_solve2( ... ): getting overflow when trying to " + "compute solution vector with bbp = %d. Choose smaller bbp.\n", bbpA ); + */ + + return FALSE; + } + + /* shift left */ + shiftL = bbpA - bbpL; + for( iL = 0; iL < sizeL; iL++ ) vecL[ iL ] <<= shiftL; + } + + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Int32Mat.h b/Embedded/common/src/b_TensorEm/Int32Mat.h new file mode 100644 index 0000000..02bb1ee --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Int32Mat.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_INT32MAT_EM_H +#define bts_INT32MAT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Int32Arr.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bts_INT32MAT_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** square matrix */ +struct bts_Int32Mat +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /* width = height of square matrix */ + uint32 widthE; + + /* array of matrix elements (data is arranged by rows) */ + struct bbs_Int32Arr arrE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes matrix */ +void bts_Int32Mat_init( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA ); + +/** destroys matric */ +void bts_Int32Mat_exit( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* copies matrices */ +void bts_Int32Mat_copy( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA, + const struct bts_Int32Mat* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates square matrix */ +void bts_Int32Mat_create( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA, + int32 widthA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Int32Mat_memSize( struct bbs_Context* cpA, + const struct bts_Int32Mat* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Int32Mat_memWrite( struct bbs_Context* cpA, + const struct bts_Int32Mat* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Int32Mat_memRead( struct bbs_Context* cpA, + struct bts_Int32Mat* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** computes the solution to matrix * outVecA = inVecA, returns false if the + * function was not successful; + * internally calls solve2() which is overflow safe; + * use large bbpA if you need high accuracy; + * + * matA: the square matrix, array of size ( matWidthA * matWidthA ) + * matWidthA: width of the matrix + * inVecA: array of size matWidthA + * outVecA: array of size matWidthA + * bbpA: bbp for all matrices and vectors + * tmpMatA: matrix of same size as matA + * tmpVecA: array of size matWidthA + */ +flag bts_Int32Mat_solve( struct bbs_Context* cpA, + const int32* matA, + int32 matWidthA, + const int32* inVecA, + int32* outVecA, + int32 bbpA, + int32* tmpMatA, + int32* tmpVecA ); + +/** same as _solve(), but matA gets overwritten, and tmpMatA is not needed: + * saves memory when matA is large; + * overflow safe; + * use large bbpA if you need high accuracy; + */ +flag bts_Int32Mat_solve2( struct bbs_Context* cpA, + int32* matA, + int32 matWidthA, + const int32* inVecA, + int32* outVecA, + int32 bbpA, + int32* tmpVecA ); + +#endif /* bts_INT32MAT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/MapSequence.c b/Embedded/common/src/b_TensorEm/MapSequence.c new file mode 100644 index 0000000..a2e1ad0 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/MapSequence.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_TensorEm/MapSequence.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_MapSequence_init( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA ) +{ + ptrA->ptrArrE = NULL; + bts_Flt16Vec_init( cpA, &ptrA->vecE ); + bts_VectorMap_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bts_VM_MAP_SEQUENCE; + ptrA->baseE.vpMapE = bts_MapSequence_map; + ptrA->sizeE = 0; + ptrA->vecSizeE = 0; + bbs_UInt16Arr_init( cpA, &ptrA->objBufE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_MapSequence_exit( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA ) +{ + uint16 iL; + for( iL = 0; iL < ptrA->sizeE; iL++ ) bts_vectorMapExit( cpA, ptrA->ptrArrE[ iL ] ); + ptrA->ptrArrE = NULL; + bts_Flt16Vec_exit( cpA, &ptrA->vecE ); + ptrA->sizeE = 0; + ptrA->vecSizeE = 0; + bbs_UInt16Arr_exit( cpA, &ptrA->objBufE ); + + bts_VectorMap_exit( cpA, &ptrA->baseE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_MapSequence_copy( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA, + const struct bts_MapSequence* srcPtrA ) +{ + bbs_ERROR0( "bts_MapSequence_copy:\n Function is not available" ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_MapSequence_equal( struct bbs_Context* cpA, + const struct bts_MapSequence* ptrA, + const struct bts_MapSequence* srcPtrA ) +{ + bbs_ERROR0( "bts_MapSequence_equal:\n Function is not available" ); + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_MapSequence_memSize( struct bbs_Context* cpA, + const struct bts_MapSequence* ptrA ) +{ + uint16 iL; + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bts_VectorMap_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_SIZEOF16( ptrA->sizeE ); + memSizeL += bbs_SIZEOF16( ptrA->vecSizeE ); + for( iL = 0; iL < ptrA->sizeE; iL++ ) memSizeL += bts_vectorMapMemSize( cpA, ptrA->ptrArrE[ iL ] ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_MapSequence_memWrite( struct bbs_Context* cpA, + const struct bts_MapSequence* ptrA, + uint16* memPtrA ) +{ + uint16 iL; + uint32 memSizeL = bts_MapSequence_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_MAP_SEQUENCE_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->vecSizeE, memPtrA ); + for( iL = 0; iL < ptrA->sizeE; iL++ ) memPtrA += bts_vectorMapMemWrite( cpA, ptrA->ptrArrE[ iL ], memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_MapSequence_memRead( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint16 iL; + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + struct bbs_MemSeg* sspL = bbs_MemTbl_sharedSegPtr( cpA, &memTblL, 0 ); + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_MAP_SEQUENCE_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->sizeE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->vecSizeE, memPtrA ); + + /* put buffer vector on shared memory */ + bts_Flt16Vec_create( cpA, &ptrA->vecE, ptrA->vecSizeE, sspL ); + + /* check maps & allocate data buffer */ + { + const uint16* memPtrL = memPtrA; + uint32 dataSizeL = ptrA->sizeE * bbs_SIZEOF16( struct bts_VectorMap* ); + + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + enum bts_VectorMapType typeL = ( enum bts_VectorMapType )bbs_memPeek32( memPtrL + 4 ); + dataSizeL += bts_vectorMapSizeOf16( cpA, typeL ); + memPtrL += bbs_memPeek32( memPtrL ); + } + + bbs_UInt16Arr_create( cpA, &ptrA->objBufE, dataSizeL, espL ); + if( bbs_Context_error( cpA ) ) return 0; + } + + /* load maps & initialize pointers */ + { + uint16* dataPtrL = ptrA->objBufE.arrPtrE; + ptrA->ptrArrE = ( struct bts_VectorMap** )dataPtrL; + dataPtrL += ptrA->sizeE * bbs_SIZEOF16( struct bts_VectorMap* ); + for( iL = 0; iL < ptrA->sizeE; iL++ ) + { + enum bts_VectorMapType typeL = ( enum bts_VectorMapType )bbs_memPeek32( memPtrA + 4 ); + ptrA->ptrArrE[ iL ] = ( struct bts_VectorMap* )dataPtrL; + bts_vectorMapInit( cpA, ptrA->ptrArrE[ iL ], typeL ); + memPtrA += bts_vectorMapMemRead( cpA, ptrA->ptrArrE[ iL ], memPtrA, &memTblL ); + dataPtrL += bts_vectorMapSizeOf16( cpA, typeL ); + } + } + + if( memSizeL != bts_MapSequence_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_MapSequence_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_MapSequence_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ) +{ + struct bts_MapSequence* ptrL = ( struct bts_MapSequence* )ptrA; + if( ptrL->sizeE == 0 ) + { + bts_Flt16Vec_copy( cpA, outVecPtrA, inVecPtrA ); + } + else if( ptrL->sizeE == 1 ) + { + struct bts_VectorMap* mapPtrL = ptrL->ptrArrE[ 0 ]; + mapPtrL->vpMapE( cpA, mapPtrL, inVecPtrA, outVecPtrA ); + } + else + { + uint32 iL; + struct bts_Flt16Vec* vp1L = &ptrL->vecE; + struct bts_Flt16Vec* vp2L = outVecPtrA; + struct bts_VectorMap* mapPtrL = ptrL->ptrArrE[ 0 ]; + mapPtrL->vpMapE( cpA, mapPtrL, inVecPtrA, vp1L ); + + for( iL = 1; iL < ptrL->sizeE; iL++ ) + { + mapPtrL = ptrL->ptrArrE[ iL ]; + mapPtrL->vpMapE( cpA, mapPtrL, vp1L, vp2L ); + + /* swap vectors */ + { + struct bts_Flt16Vec* vpL = vp1L; + vp1L = vp2L; + vp2L = vpL; + } + } + + /* vp1 holds output */ + if( vp1L != outVecPtrA ) bts_Flt16Vec_copy( cpA, outVecPtrA, vp1L ); + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/MapSequence.h b/Embedded/common/src/b_TensorEm/MapSequence.h new file mode 100644 index 0000000..2a701d5 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/MapSequence.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_MAP_SEQUENCE_EM_H +#define bts_MAP_SEQUENCE_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Int32Arr.h" +#include "b_BasicEm/UInt16Arr.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/VectorMap.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** data format version number */ +#define bts_MAP_SEQUENCE_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** sequence of vector maps */ +struct bts_MapSequence +{ + /* ---- public data ---------------------------------------------------- */ + + /** base element (must be first element) */ + struct bts_VectorMap baseE; + + /* ---- private data --------------------------------------------------- */ + + /** internal vector */ + struct bts_Flt16Vec vecE; + + /* ---- public data ---------------------------------------------------- */ + + /** map sequence size */ + uint32 sizeE; + + /** preallocation size for internal vector */ + uint32 vecSizeE; + + /** object buffer */ + struct bbs_UInt16Arr objBufE; + + /** map pointer arrray */ + struct bts_VectorMap** ptrArrE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bts_MapSequence */ +void bts_MapSequence_init( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA ); + +/** resets bts_MapSequence */ +void bts_MapSequence_exit( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_MapSequence_copy( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA, + const struct bts_MapSequence* srcPtrA ); + +/** equal operator */ +flag bts_MapSequence_equal( struct bbs_Context* cpA, + const struct bts_MapSequence* ptrA, + const struct bts_MapSequence* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bts_MapSequence_memSize( struct bbs_Context* cpA, + const struct bts_MapSequence* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_MapSequence_memWrite( struct bbs_Context* cpA, + const struct bts_MapSequence* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_MapSequence_memRead( struct bbs_Context* cpA, + struct bts_MapSequence* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Vector map operation. + * Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + */ +void bts_MapSequence_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ); + +#endif /* bts_MAP_SEQUENCE_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Mat.c b/Embedded/common/src/b_TensorEm/Mat.c new file mode 100644 index 0000000..3525225 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Mat.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_TensorEm/Mat.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Mat_init( struct bbs_Context* cpA, + struct bts_Mat* ptrA ) +{ + bts_VectorMap_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bts_VM_MAT; + ptrA->baseE.vpMapE = bts_Mat_map; + + bts_CompactMat_init( cpA, &ptrA->matE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_Mat_exit( struct bbs_Context* cpA, + struct bts_Mat* ptrA ) +{ + bts_CompactMat_exit( cpA, &ptrA->matE ); + + bts_VectorMap_exit( cpA, &ptrA->baseE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Mat_copy( struct bbs_Context* cpA, + struct bts_Mat* ptrA, + const struct bts_Mat* srcPtrA ) +{ + bts_CompactMat_copy( cpA, &ptrA->matE, &srcPtrA->matE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Mat_equal( struct bbs_Context* cpA, + const struct bts_Mat* ptrA, + const struct bts_Mat* srcPtrA ) +{ + bbs_ERROR0( "bts_Mat_equal:\n Function is not available" ); + return FALSE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Mat_memSize( struct bbs_Context* cpA, + const struct bts_Mat* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + + memSizeL += bts_VectorMap_memSize( cpA, &ptrA->baseE ); + memSizeL += bts_CompactMat_memSize( cpA, &ptrA->matE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Mat_memWrite( struct bbs_Context* cpA, + const struct bts_Mat* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Mat_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_MAT_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bts_CompactMat_memWrite( cpA, &ptrA->matE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Mat_memRead( struct bbs_Context* cpA, + struct bts_Mat* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + struct bbs_MemTbl memTblL = *mtpA; + struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 ); + + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_MAT_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bts_CompactMat_memRead( cpA, &ptrA->matE, memPtrA, espL ); + + if( memSizeL != bts_Mat_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Mat_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Mat_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ) +{ + bbs_DEF_fNameL( "bts_Mat_map" ) + const struct bts_Mat* ptrL = ( const struct bts_Mat* )ptrA; + + if( inVecPtrA->arrE.sizeE != ptrL->matE.widthE ) + { + bbs_ERROR1( "%s:\ninput vector has incorrect size", fNameL ); + return; + } + + if( outVecPtrA->arrE.allocatedSizeE < ptrL->matE.heightE ) + { + bbs_ERROR1( "%s:\noutput vector is insufficiently allocated", fNameL ); + return; + } + + bts_Flt16Vec_size( cpA, outVecPtrA, ptrL->matE.heightE ); + + { + int16 expL = 0; + int32 outExpL = inVecPtrA->expE; + bts_CompactMat_map( cpA, &ptrL->matE, inVecPtrA->arrE.arrPtrE, outVecPtrA->arrE.arrPtrE, &expL ); + outExpL += expL; + + /* precision underflow */ + if( outExpL < -32767 ) bts_Flt16Vec_setZero( cpA, outVecPtrA ); + } + + bts_Flt16Vec_maximizeMantisse( cpA, outVecPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Mat.h b/Embedded/common/src/b_TensorEm/Mat.h new file mode 100644 index 0000000..04c7a95 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Mat.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_MAT_EM_H +#define bts_MAT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/VectorMap.h" +#include "b_TensorEm/CompactMat.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** data format version number */ +#define bts_MAT_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** affine linear transformation to vector */ +struct bts_Mat +{ + /* ---- public data ---------------------------------------------------- */ + + /** base element (must be first element) */ + struct bts_VectorMap baseE; + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /* linear transformation */ + struct bts_CompactMat matE; + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bts_Mat */ +void bts_Mat_init( struct bbs_Context* cpA, + struct bts_Mat* ptrA ); + +/** resets bts_Mat */ +void bts_Mat_exit( struct bbs_Context* cpA, + struct bts_Mat* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_Mat_copy( struct bbs_Context* cpA, + struct bts_Mat* ptrA, + const struct bts_Mat* srcPtrA ); + +/** equal operator */ +flag bts_Mat_equal( struct bbs_Context* cpA, + const struct bts_Mat* ptrA, + const struct bts_Mat* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bts_Mat_memSize( struct bbs_Context* cpA, + const struct bts_Mat* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_Mat_memWrite( struct bbs_Context* cpA, + const struct bts_Mat* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_Mat_memRead( struct bbs_Context* cpA, + struct bts_Mat* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Vector map operation. + * Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + */ +void bts_Mat_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ); + +#endif /* bts_MAT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Normalizer.c b/Embedded/common/src/b_TensorEm/Normalizer.c new file mode 100644 index 0000000..b6b26a2 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Normalizer.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_TensorEm/Normalizer.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Normalizer_init( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA ) +{ + bts_VectorMap_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bts_VM_NORMALIZER; + ptrA->baseE.vpMapE = bts_Normalizer_map; +} + +/* ------------------------------------------------------------------------- */ + +void bts_Normalizer_exit( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA ) +{ + bts_VectorMap_exit( cpA, &ptrA->baseE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Normalizer_copy( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA, + const struct bts_Normalizer* srcPtrA ) +{ +} + +/* ------------------------------------------------------------------------- */ + +flag bts_Normalizer_equal( struct bbs_Context* cpA, + const struct bts_Normalizer* ptrA, + const struct bts_Normalizer* srcPtrA ) +{ + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Normalizer_memSize( struct bbs_Context* cpA, + const struct bts_Normalizer* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + memSizeL += bts_VectorMap_memSize( cpA, &ptrA->baseE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Normalizer_memWrite( struct bbs_Context* cpA, + const struct bts_Normalizer* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_Normalizer_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_NORMALIZER_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memWrite( cpA, &ptrA->baseE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Normalizer_memRead( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_NORMALIZER_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memRead( cpA, &ptrA->baseE, memPtrA ); + + if( memSizeL != bts_Normalizer_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_Normalizer_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_Normalizer_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ) +{ + bts_Flt16Vec_copy( cpA, outVecPtrA, inVecPtrA ); + bts_Flt16Vec_normalize( cpA, outVecPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/Normalizer.h b/Embedded/common/src/b_TensorEm/Normalizer.h new file mode 100644 index 0000000..20e9d02 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Normalizer.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_NORMALIZER_EM_H +#define bts_NORMALIZER_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/VectorMap.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** data format version number */ +#define bts_NORMALIZER_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** applies euclidean normalization to vector */ +struct bts_Normalizer +{ + /* ---- public data ---------------------------------------------------- */ + + /** base element (must be first element) */ + struct bts_VectorMap baseE; + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bts_Normalizer */ +void bts_Normalizer_init( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA ); + +/** resets bts_Normalizer */ +void bts_Normalizer_exit( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_Normalizer_copy( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA, + const struct bts_Normalizer* srcPtrA ); + +/** equal operator */ +flag bts_Normalizer_equal( struct bbs_Context* cpA, + const struct bts_Normalizer* ptrA, + const struct bts_Normalizer* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bts_Normalizer_memSize( struct bbs_Context* cpA, + const struct bts_Normalizer* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_Normalizer_memWrite( struct bbs_Context* cpA, + const struct bts_Normalizer* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_Normalizer_memRead( struct bbs_Context* cpA, + struct bts_Normalizer* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Vector map operation. + * Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + */ +void bts_Normalizer_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ); + +#endif /* bts_NORMALIZER_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/RBFMap2D.c b/Embedded/common/src/b_TensorEm/RBFMap2D.c new file mode 100644 index 0000000..722ce15 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/RBFMap2D.c @@ -0,0 +1,585 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/RBFMap2D.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_RBFMap2D_init( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA ) +{ + ptrA->RBFTypeE = bts_RBF_LINEAR; + bts_Cluster2D_init( cpA, &ptrA->srcClusterE ); + bts_Cluster2D_init( cpA, &ptrA->rbfCoeffClusterE ); + ptrA->altTypeE = bts_ALT_LINEAR; + bts_Flt16Alt2D_init( &ptrA->altE ); + + ptrA->altOnlyE = FALSE; + + bts_Int32Mat_init( cpA, &ptrA->matE ); + bts_Int32Mat_init( cpA, &ptrA->tempMatE ); + bbs_Int32Arr_init( cpA, &ptrA->inVecE ); + bbs_Int32Arr_init( cpA, &ptrA->outVecE ); + bbs_Int32Arr_init( cpA, &ptrA->tempVecE ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_RBFMap2D_exit( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA ) +{ + ptrA->RBFTypeE = bts_RBF_LINEAR; + bts_Cluster2D_exit( cpA, &ptrA->srcClusterE ); + bts_Cluster2D_exit( cpA, &ptrA->rbfCoeffClusterE ); + ptrA->altTypeE = bts_ALT_LINEAR; + bts_Flt16Alt2D_exit( &ptrA->altE ); + + ptrA->altOnlyE = FALSE; + + bts_Int32Mat_exit( cpA, &ptrA->matE ); + bts_Int32Mat_exit( cpA, &ptrA->tempMatE ); + bbs_Int32Arr_exit( cpA, &ptrA->inVecE ); + bbs_Int32Arr_exit( cpA, &ptrA->outVecE ); + bbs_Int32Arr_exit( cpA, &ptrA->tempVecE ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_RBFMap2D_copy( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + const struct bts_RBFMap2D* srcPtrA ) +{ + ptrA->RBFTypeE = srcPtrA->RBFTypeE; + bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, &srcPtrA->srcClusterE ); + bts_Cluster2D_copy( cpA, &ptrA->rbfCoeffClusterE, &srcPtrA->rbfCoeffClusterE ); + ptrA->altTypeE = srcPtrA->altTypeE; + bts_Flt16Alt2D_copy( &ptrA->altE, &srcPtrA->altE ); +} + +/* ------------------------------------------------------------------------- */ + +flag bts_RBFMap2D_equal( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + const struct bts_RBFMap2D* srcPtrA ) +{ + if( ptrA->RBFTypeE != srcPtrA->RBFTypeE ) return FALSE; + if( ! bts_Cluster2D_equal( cpA, &ptrA->srcClusterE, &srcPtrA->srcClusterE ) ) return FALSE; + if( ! bts_Cluster2D_equal( cpA, &ptrA->rbfCoeffClusterE, &srcPtrA->rbfCoeffClusterE ) ) return FALSE; + if( ptrA->altTypeE != srcPtrA->altTypeE ) return FALSE; + if( ! bts_Flt16Alt2D_equal( &ptrA->altE, &srcPtrA->altE ) ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_RBFMap2D_create( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ) +{ + if( bbs_Context_error( cpA ) ) return; + bts_Cluster2D_create( cpA, &ptrA->srcClusterE, sizeA, mspA ); + bts_Cluster2D_create( cpA, &ptrA->rbfCoeffClusterE, sizeA, mspA ); + + bts_Int32Mat_create( cpA, &ptrA->matE, sizeA, mspA ); + bts_Int32Mat_create( cpA, &ptrA->tempMatE, sizeA, mspA ); + bbs_Int32Arr_create( cpA, &ptrA->inVecE, sizeA, mspA ); + bbs_Int32Arr_create( cpA, &ptrA->outVecE, sizeA, mspA ); + bbs_Int32Arr_create( cpA, &ptrA->tempVecE, sizeA, mspA ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_RBFMap2D_compute( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + const struct bts_Cluster2D* srcPtrA, + const struct bts_Cluster2D* dstPtrA ) +{ + const uint32 sizeL = srcPtrA->sizeE; + int32 bbp_internalL = 15; + int32 bbp_rbfCoeffL = 12; + + int32 internalShiftL = bbp_internalL - srcPtrA->bbpE; + int32 rbfCoeffShiftL; + + uint32 iL, jL; + + if( dstPtrA->sizeE != srcPtrA->sizeE ) + { + bbs_ERROR2( "void bts_RBFMap2D_compute( ... ): size mismatch, src cluster has size %d," + "but dst cluster has size %d\n", srcPtrA->sizeE, dstPtrA->sizeE ); + return; + } + + ptrA->altOnlyE = FALSE; + + /* if bbp of src cluster should be larger than bbp_internal, use it instead */ + if( internalShiftL < 0 ) + { + internalShiftL = 0; + bbp_internalL = srcPtrA->bbpE; + } + + /* also checks for sizeL > allocated size */ + bts_Cluster2D_size( cpA, &ptrA->rbfCoeffClusterE, sizeL ); + + /* set rbf coefficients to 0 in case they don't get computed */ + for( iL =0; iL < sizeL; iL++ ) + { + ptrA->rbfCoeffClusterE.vecArrE[ iL ].xE = 0; + ptrA->rbfCoeffClusterE.vecArrE[ iL ].yE = 0; + } + + /* 1. Compute rigid transformation: if cluster size == 0 returns identity */ + ptrA->altE = bts_Cluster2D_alt( cpA, srcPtrA, dstPtrA, ptrA->altTypeE ); + + /* if cluster size is less than 3 affine trafo covers whole transformation */ + if( sizeL < 3 ) + { + bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, srcPtrA ); + ptrA->altOnlyE = TRUE; + return; + } + + /* 2. Compute RBF trafo */ + ptrA->matE.widthE = sizeL; + ptrA->tempMatE.widthE = sizeL; + + /* Set up linear matrix to invert */ + switch( ptrA->RBFTypeE ) + { + case bts_RBF_IDENTITY: + { + return; + } + + case bts_RBF_LINEAR: + { + /* ||r|| */ + for( iL = 0; iL < sizeL; iL++ ) + { + struct bts_Int16Vec2D vec0L = srcPtrA->vecArrE[ iL ]; + int32* ptrL = ptrA->matE.arrE.arrPtrE + iL * sizeL; + + /* set diagonal elements having null distance */ + *( ptrL + iL ) = 0; + + for( jL = 0; jL < iL; jL++ ) /* use symmetry */ + { + int32 normL = 0; + struct bts_Int16Vec2D vecL = srcPtrA->vecArrE[ jL ]; + vecL.xE -= vec0L.xE; + vecL.yE -= vec0L.yE; + normL = bts_Int16Vec2D_norm( &vecL ); + *ptrL++ = normL << internalShiftL; + } + } + } + break; + + /* Add a new RBF type here */ + + default: + { + bbs_ERROR1( "void bts_RBFMap2D_compute( ... ): RBFType %d is not handled\n", ptrA->RBFTypeE ); + return; + } + } + + /* use symmetry: set symmetric elements in matrix */ + for( iL = 0; iL < sizeL; iL++ ) + { + int32* basePtrL = ptrA->matE.arrE.arrPtrE; + uint32 jL; + for( jL = iL + 1; jL < sizeL; jL++ ) + { + *( basePtrL + iL * sizeL + jL ) = *( basePtrL + jL * sizeL + iL ); + } + } + + /* Precompute alt transformed cluster, srcClusterE will be restored at the end */ + bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, srcPtrA ); + bts_Cluster2D_transformBbp( cpA, &ptrA->srcClusterE, ptrA->altE, dstPtrA->bbpE ); + + bbs_Int32Arr_size( cpA, &ptrA->inVecE, sizeL ); + bbs_Int32Arr_size( cpA, &ptrA->outVecE, sizeL ); + bbs_Int32Arr_size( cpA, &ptrA->tempVecE, sizeL ); + + { + flag successL; + + /* compute right side vector of linear system to be solved, for x */ + int32* inPtrL = ptrA->inVecE.arrPtrE; + struct bts_Int16Vec2D* dstVecL = dstPtrA->vecArrE; + struct bts_Int16Vec2D* altVecL = ptrA->srcClusterE.vecArrE; + + int32 shiftL = srcPtrA->bbpE - ptrA->srcClusterE.bbpE + internalShiftL; + if( shiftL >= 0 ) + { + for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( int32 )( dstVecL[ iL ].xE - altVecL[ iL ].xE ) << shiftL; + } + else + { + for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( ( ( int32 )( dstVecL[ iL ].xE - altVecL[ iL ].xE ) >> ( ( -shiftL ) - 1 ) ) + 1 ) >> 1; + } + + /* solve linear system in x */ + successL = bts_Int32Mat_solve( cpA, + ptrA->matE.arrE.arrPtrE, + sizeL, + ptrA->inVecE.arrPtrE, + ptrA->outVecE.arrPtrE, + bbp_internalL, + ptrA->tempMatE.arrE.arrPtrE, + ptrA->tempVecE.arrPtrE ); + + /* no error condition here! system must be failsafe */ + if( !successL ) ptrA->altOnlyE = TRUE; + + /* store rbf coefficients, x component */ + rbfCoeffShiftL = bbp_internalL - bbp_rbfCoeffL; + for( iL = 0; iL < sizeL; iL++ ) + { + int32 rbfCoeffL = ptrA->outVecE.arrPtrE[ iL ] >> rbfCoeffShiftL; + if( rbfCoeffL < -32768 || rbfCoeffL > 32767 ) ptrA->altOnlyE = TRUE; /* check for overflow */ + ptrA->rbfCoeffClusterE.vecArrE[ iL ].xE = rbfCoeffL; + } + + + /* compute right side vector of linear system to be solved, for y */ + if( shiftL >= 0 ) + { + for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( int32 )( dstVecL[ iL ].yE - altVecL[ iL ].yE ) << shiftL; + } + else + { + for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( ( ( int32 )( dstVecL[ iL ].yE - altVecL[ iL ].yE ) >> ( ( -shiftL ) - 1 ) ) + 1 ) >> 1; + } + + /* solve linear system in y */ + successL = bts_Int32Mat_solve( cpA, + ptrA->matE.arrE.arrPtrE, + sizeL, + ptrA->inVecE.arrPtrE, + ptrA->outVecE.arrPtrE, + bbp_internalL, + ptrA->tempMatE.arrE.arrPtrE, + ptrA->tempVecE.arrPtrE ); + if( !successL ) + { + /* no error condition here! system must be failsafe */ + ptrA->altOnlyE = TRUE; + } + + /* store rbf coefficients, y component */ + for( iL = 0; iL < sizeL; iL++ ) + { + int32 rbfCoeffL = ptrA->outVecE.arrPtrE[ iL ] >> rbfCoeffShiftL; + if( rbfCoeffL < -32768 || rbfCoeffL > 32767 ) ptrA->altOnlyE = TRUE; /* check for overflow */ + ptrA->rbfCoeffClusterE.vecArrE[ iL ].yE = rbfCoeffL; + } + + /* set bbp of coeff cluster */ + ptrA->rbfCoeffClusterE.bbpE = bbp_rbfCoeffL; + } + + /** after having used srcClusterE for temporary storage of the alt src cluster, + restore the orig src cluster as needed for the RBF trafo */ + bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, srcPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_RBFMap2D_memSize( struct bbs_Context* cpA, + const struct bts_RBFMap2D *ptrA ) +{ + return bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ) /* version */ + + bbs_SIZEOF16( ptrA->RBFTypeE ) + + bts_Cluster2D_memSize( cpA, &ptrA->srcClusterE ) + + bts_Cluster2D_memSize( cpA, &ptrA->rbfCoeffClusterE ) + + bbs_SIZEOF16( ptrA->altTypeE ) + + bts_Flt16Alt2D_memSize( cpA, &ptrA->altE ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_RBFMap2D_memWrite( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_RBFMap2D_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_IRBFMAP2D_VERSION, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->RBFTypeE, memPtrA ); + memPtrA += bts_Cluster2D_memWrite( cpA, &ptrA->srcClusterE, memPtrA ); + memPtrA += bts_Cluster2D_memWrite( cpA, &ptrA->rbfCoeffClusterE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->altTypeE, memPtrA ); + memPtrA += bts_Flt16Alt2D_memWrite( cpA, &ptrA->altE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_RBFMap2D_memRead( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_IRBFMAP2D_VERSION, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->RBFTypeE, memPtrA ); + memPtrA += bts_Cluster2D_memRead( cpA, &ptrA->srcClusterE, memPtrA, mspA ); + memPtrA += bts_Cluster2D_memRead( cpA, &ptrA->rbfCoeffClusterE, memPtrA, mspA ); + memPtrA += bbs_memRead32( &ptrA->altTypeE, memPtrA ); + memPtrA += bts_Flt16Alt2D_memRead( cpA, &ptrA->altE, memPtrA ); + + bts_Int32Mat_create( cpA, &ptrA->matE, ptrA->srcClusterE.sizeE, mspA ); + bts_Int32Mat_create( cpA, &ptrA->tempMatE, ptrA->srcClusterE.sizeE, mspA ); + + if( memSizeL != bts_RBFMap2D_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_RBFMap2D_memRead( ... ): size mismatch\n" ); + return 0; + } + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/** R, A are rbf and A affine linear transformations + * T( x ) = R( x ) + A( x ) + */ +struct bts_Flt16Vec2D bts_RBFMap2D_mapVector( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + struct bts_Flt16Vec2D vecA ) +{ + const uint32 sizeL = ptrA->srcClusterE.sizeE; + const int32 bbp_internalL = ptrA->rbfCoeffClusterE.bbpE; + uint32 iL; + int32 shL; + + int32 outXL; + int32 outYL; + int32 outBbpL; + + /* 1. Compute rigid transformation, i.e. A( x ) */ + struct bts_Flt16Vec2D altVecL = bts_Flt16Alt2D_mapFlt( &ptrA->altE, &vecA ); + + /* compute output on 32 bit here to prevent temporary overflows (j.s.) */ + outXL = altVecL.xE; + outYL = altVecL.yE; + outBbpL = altVecL.bbpE; + + /* if bbp was altered, change it back to bbp of vecA ( det A is always close to 1 here ) */ + shL = vecA.bbpE - outBbpL; + if( shL > 0 ) + { + outXL <<= shL; + outYL <<= shL; + } + else if( shL < 0 ) + { + outXL = ( ( outXL >> ( -shL - 1 ) ) + 1 ) >> 1; + outYL = ( ( outYL >> ( -shL - 1 ) ) + 1 ) >> 1; + } + outBbpL = vecA.bbpE; + + /* stop here if rbf coefficients could not be computed */ + if( ptrA->altOnlyE ) + { + return bts_Flt16Vec2D_create32( outXL, outYL, outBbpL ); + } + + /* 2. Compute RBF transformation, i.e. R( x ) depending on type */ + switch( ptrA->RBFTypeE ) + { + case bts_RBF_IDENTITY: + break; + + case bts_RBF_LINEAR: + { + int32 xSumL = 0; + int32 ySumL = 0; + int32 internalShiftL = bbp_internalL - ptrA->srcClusterE.bbpE; + + /* first adapt vecA to bbp of srcCluster */ + int32 xL = vecA.xE; + int32 yL = vecA.yE; + int32 shiftL = ptrA->srcClusterE.bbpE - vecA.bbpE; + if( shiftL > 0 ) + { + xL <<= shiftL; + yL <<= shiftL; + } + else if( shiftL < 0 ) + { + xL = ( ( xL >> ( -shiftL - 1 ) ) + 1 ) >> 1; + yL = ( ( yL >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } + + shiftL = ptrA->srcClusterE.bbpE; + + for( iL = 0; iL < sizeL; iL++ ) + { + struct bts_Int16Vec2D vecL = ptrA->srcClusterE.vecArrE[ iL ]; + int32 normL = 0; + vecL.xE -= xL; + vecL.yE -= yL; + normL = bts_Int16Vec2D_norm( &vecL ); + +/* printf( "iL = %d, norm = %d\n", iL, normL ); */ + + xSumL += ( normL * ptrA->rbfCoeffClusterE.vecArrE[ iL ].xE ) >> shiftL; + ySumL += ( normL * ptrA->rbfCoeffClusterE.vecArrE[ iL ].yE ) >> shiftL; + +/* printf( "iL = %d, xSumL = %d, ySumL = %d\n", iL, xSumL, ySumL ); */ + + } + + xSumL >>= internalShiftL; + ySumL >>= internalShiftL; + + /* change bbp of result back to bbp of vecA */ + /* shiftL = vecA.bbpE - ptrA->srcClusterE.bbpE - internalShiftL; */ + shiftL = vecA.bbpE - ptrA->srcClusterE.bbpE; + if( shiftL > 0 ) + { + xSumL <<= shiftL; + ySumL <<= shiftL; + } + else if( shiftL < 0 ) + { + xSumL = ( ( xSumL >> ( -shiftL - 1 ) ) + 1 ) >> 1; + ySumL = ( ( ySumL >> ( -shiftL - 1 ) ) + 1 ) >> 1; + } + + /* add rbf part to already computed alt part */ + outXL += xSumL; + outYL += ySumL; + } + break; + + /* Add a new RBF type here */ + + default: + { + bbs_ERROR1( "struct bts_Flt16Vec2D bts_RBFMap2D_mapVector( ... ): " + "RBFType %d is not handled\n", ptrA->RBFTypeE ); + return bts_Flt16Vec2D_create32( outXL, outYL, outBbpL ); + } + } + + return bts_Flt16Vec2D_create32( outXL, outYL, outBbpL ); +} + +/* ------------------------------------------------------------------------- */ + +void bts_RBFMap2D_mapCluster( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + const struct bts_Cluster2D* srcPtrA, + struct bts_Cluster2D* dstPtrA, + int32 dstBbpA ) +{ + if( dstPtrA->sizeE != srcPtrA->sizeE ) + { + /* resizing of clusters is allowed as long as allocated size is not exceeded */ + bts_Cluster2D_size( cpA, dstPtrA, srcPtrA->sizeE ); + } + + { + uint32 iL; + int16 bbpL = srcPtrA->bbpE; + + dstPtrA->bbpE = dstBbpA; + + for( iL = 0; iL < srcPtrA->sizeE; iL++ ) + { + struct bts_Int16Vec2D vecL = srcPtrA->vecArrE[ iL ]; + struct bts_Flt16Vec2D srcVecL = bts_Flt16Vec2D_create16( vecL.xE, vecL.yE, bbpL ); + struct bts_Flt16Vec2D dstVecL = bts_RBFMap2D_mapVector( cpA, ptrA, srcVecL ); + dstPtrA->vecArrE[ iL ].xE = bbs_convertS32( dstVecL.xE, dstVecL.bbpE, dstBbpA ); + dstPtrA->vecArrE[ iL ].yE = bbs_convertS32( dstVecL.yE, dstVecL.bbpE, dstBbpA ); + } + } +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/RBFMap2D.h b/Embedded/common/src/b_TensorEm/RBFMap2D.h new file mode 100644 index 0000000..ba30867 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/RBFMap2D.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_RBFMAP2D_EM_H +#define bts_RBFMAP2D_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/Int16Arr.h" +#include "b_TensorEm/Int16Vec2D.h" +#include "b_TensorEm/Flt16Vec2D.h" +#include "b_TensorEm/Flt16Alt2D.h" +#include "b_TensorEm/Functions.h" +#include "b_TensorEm/Cluster2D.h" +#include "b_TensorEm/Int32Mat.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* data format version number */ +#define bts_IRBFMAP2D_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** + * radial basis function transformation (RBF). + * T( x ) = A( x ) + R( x ) where, + * T is the resulting overall tranformation + * A is a possibly linear tranformation of type altTypeE + * R is the rbf ( non-linear ) transformation of type typeE + * See member declaration for more information on typeE and altTypeE. + * See also + * 'Image Warping Using few Anchor Points and Radial Functions', + * Nur Arad and Daniel Reisfeld, 1994 + */ +struct bts_RBFMap2D +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** type of radial basis function (enum bts_RBFType). + * one of: + * bts_RBF_IDENTITY : no rbf deformation + * bts_RBF_LINEAr : linear, i.e. ||r|| + */ + int32 RBFTypeE; + + /** src cluster, part of the RBF trafo */ + struct bts_Cluster2D srcClusterE; + + /** cluster of rbf coefficients, x and y */ + struct bts_Cluster2D rbfCoeffClusterE; + + /** type of linear transformation (enum bts_AltType) */ + int32 altTypeE; + + /** affine linear transformation */ + struct bts_Flt16Alt2D altE; + + /** apply only affine lnear transformation */ + flag altOnlyE; + + /* ---- temporary data ------------------------------------------------- */ + + /** matrix needed for computation of rbf coefficients */ + struct bts_Int32Mat matE; + struct bts_Int32Mat tempMatE; + + /** arrays needed for computation of rbf coefficients */ + struct bbs_Int32Arr inVecE; + struct bbs_Int32Arr outVecE; + struct bbs_Int32Arr tempVecE; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes RBFMap */ +void bts_RBFMap2D_init( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA ); + +/** destroys RBFMap */ +void bts_RBFMap2D_exit( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copies RBFMap */ +void bts_RBFMap2D_copy( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + const struct bts_RBFMap2D* srcPtrA ); + +/** compares RBFMap */ +flag bts_RBFMap2D_equal( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + const struct bts_RBFMap2D* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/** allocates RBFMap */ +void bts_RBFMap2D_create( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + uint32 sizeA, + struct bbs_MemSeg* mspA ); + +/** computes rbf transform from 2 given clusters of same size and bbp */ +void bts_RBFMap2D_compute( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + const struct bts_Cluster2D* srcPtrA, + const struct bts_Cluster2D* dstPtrA ); + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_RBFMap2D_memSize( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_RBFMap2D_memWrite( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_RBFMap2D_memRead( struct bbs_Context* cpA, + struct bts_RBFMap2D* ptrA, + const uint16* memPtrA, + struct bbs_MemSeg* mspA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** vector map operation: apply rbf to a vector */ +struct bts_Flt16Vec2D bts_RBFMap2D_mapVector( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + struct bts_Flt16Vec2D vecA ); + +/** cluster map operation: apply rbf to all vectors in cluster */ +void bts_RBFMap2D_mapCluster( struct bbs_Context* cpA, + const struct bts_RBFMap2D* ptrA, + const struct bts_Cluster2D* srcPtrA, + struct bts_Cluster2D* dstPtrA, + int32 dstBbpA ); + +#endif /* bts_RBFMAP2D_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/SubVecMap.c b/Embedded/common/src/b_TensorEm/SubVecMap.c new file mode 100644 index 0000000..1e98338 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/SubVecMap.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_TensorEm/SubVecMap.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_SubVecMap_init( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA ) +{ + bts_VectorMap_init( cpA, &ptrA->baseE ); + ptrA->baseE.typeE = ( uint32 )bts_VM_SUB_VEC_MAP; + ptrA->baseE.vpMapE = bts_SubVecMap_map; + ptrA->offsetE = 0; + ptrA->sizeE = -1; +} + +/* ------------------------------------------------------------------------- */ + +void bts_SubVecMap_exit( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA ) +{ + bts_VectorMap_exit( cpA, &ptrA->baseE ); + ptrA->offsetE = 0; + ptrA->sizeE = -1; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_SubVecMap_copy( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA, + const struct bts_SubVecMap* srcPtrA ) +{ + ptrA->offsetE = srcPtrA->offsetE; + ptrA->sizeE = srcPtrA->sizeE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_SubVecMap_equal( struct bbs_Context* cpA, + const struct bts_SubVecMap* ptrA, + const struct bts_SubVecMap* srcPtrA ) +{ + if( ptrA->offsetE != srcPtrA->offsetE ) return FALSE; + if( ptrA->sizeE != srcPtrA->sizeE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_SubVecMap_memSize( struct bbs_Context* cpA, + const struct bts_SubVecMap* ptrA ) +{ + uint32 memSizeL = bbs_SIZEOF16( uint32 ) + + bbs_SIZEOF16( uint32 ); /* version */ + memSizeL += bts_VectorMap_memSize( cpA, &ptrA->baseE ); + memSizeL += bbs_SIZEOF16( ptrA->offsetE ); + memSizeL += bbs_SIZEOF16( ptrA->sizeE ); + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_SubVecMap_memWrite( struct bbs_Context* cpA, + const struct bts_SubVecMap* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_SubVecMap_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); + memPtrA += bbs_memWriteUInt32( bts_SUB_VEC_MAP_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memWrite( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->offsetE, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->sizeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_SubVecMap_memRead( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + uint32 memSizeL, versionL; + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &memSizeL, memPtrA ); + memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_SUB_VEC_MAP_VERSION, memPtrA ); + memPtrA += bts_VectorMap_memRead( cpA, &ptrA->baseE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->offsetE, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->sizeE, memPtrA ); + + if( memSizeL != bts_SubVecMap_memSize( cpA, ptrA ) ) + { + bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_SubVecMap_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n" + "size mismatch" ); + return 0; + } + + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_SubVecMap_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ) +{ + bbs_DEF_fNameL( "bts_SubVecMap_map" ) + struct bts_SubVecMap* ptrL = ( struct bts_SubVecMap* )ptrA; + + int32 sizeL = ( ptrL->sizeE != -1 ) ? ptrL->sizeE : ( int32 )inVecPtrA->arrE.sizeE - ptrL->offsetE; + if( sizeL < 0 ) sizeL = 0; + + if( ( ptrL->offsetE + sizeL ) > ( int32 )inVecPtrA->arrE.sizeE ) + { + bbs_ERROR1( "%s:\ninput vector too small", fNameL ); + return; + } + + if( outVecPtrA->arrE.allocatedSizeE < ( uint32 )sizeL ) + { + bbs_ERROR1( "%s:\noutput vector is insufficiently allocated", fNameL ); + return; + } + + bts_Flt16Vec_size( cpA, outVecPtrA, sizeL ); + outVecPtrA->expE = inVecPtrA->expE; + bbs_memcpy16( outVecPtrA->arrE.arrPtrE, inVecPtrA->arrE.arrPtrE + ptrL->offsetE, sizeL ); + + bts_Flt16Vec_maximizeMantisse( cpA, outVecPtrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/SubVecMap.h b/Embedded/common/src/b_TensorEm/SubVecMap.h new file mode 100644 index 0000000..629d2a4 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/SubVecMap.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_SUB_VEC_MAP_EM_H +#define bts_SUB_VEC_MAP_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/VectorMap.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/** data format version number */ +#define bts_SUB_VEC_MAP_VERSION 100 + +/* ---- object definition -------------------------------------------------- */ + +/** extracts a section from the input vector and returns it as sub-vector */ +struct bts_SubVecMap +{ + /* ---- public data ---------------------------------------------------- */ + + /** base element (must be first element) */ + struct bts_VectorMap baseE; + + /* ---- private data --------------------------------------------------- */ + + /** vector offset */ + int32 offsetE; + + /** vector size (-1: size = input size - offsetE) */ + int32 sizeE; + + /* ---- public data ---------------------------------------------------- */ + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bts_SubVecMap */ +void bts_SubVecMap_init( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA ); + +/** resets bts_SubVecMap */ +void bts_SubVecMap_exit( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_SubVecMap_copy( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA, + const struct bts_SubVecMap* srcPtrA ); + +/** equal operator */ +flag bts_SubVecMap_equal( struct bbs_Context* cpA, + const struct bts_SubVecMap* ptrA, + const struct bts_SubVecMap* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bts_SubVecMap_memSize( struct bbs_Context* cpA, + const struct bts_SubVecMap* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_SubVecMap_memWrite( struct bbs_Context* cpA, + const struct bts_SubVecMap* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_SubVecMap_memRead( struct bbs_Context* cpA, + struct bts_SubVecMap* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** Vector map operation. + * Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + */ +void bts_SubVecMap_map( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ); + +#endif /* bts_SUB_VEC_MAP_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/Uint32Rect.c b/Embedded/common/src/b_TensorEm/Uint32Rect.c new file mode 100644 index 0000000..d43f0d0 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Uint32Rect.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_TensorEm/Uint32Rect.h" +#include "b_BasicEm/Functions.h" +#include "b_BasicEm/Math.h" +#include "b_BasicEm/Memory.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Uint32Rect_memSize( struct bbs_Context* cpA, + const struct bts_Uint32Rect *ptrA ) +{ + return bbs_SIZEOF16( struct bts_Uint32Rect ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Uint32Rect_memWrite( struct bbs_Context* cpA, + const struct bts_Uint32Rect* ptrA, + uint16* memPtrA ) +{ + memPtrA += bbs_memWrite32( &ptrA->x1E, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->y1E, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->x2E, memPtrA ); + memPtrA += bbs_memWrite32( &ptrA->y2E, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_Uint32Rect_memRead( struct bbs_Context* cpA, + struct bts_Uint32Rect* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &ptrA->x1E, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->y1E, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->x2E, memPtrA ); + memPtrA += bbs_memRead32( &ptrA->y2E, memPtrA ); + return bbs_SIZEOF16( *ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + + diff --git a/Embedded/common/src/b_TensorEm/Uint32Rect.h b/Embedded/common/src/b_TensorEm/Uint32Rect.h new file mode 100644 index 0000000..e7745cb --- /dev/null +++ b/Embedded/common/src/b_TensorEm/Uint32Rect.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_UINT32RECT_EM_H +#define bts_UINT32RECT_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** 2d vector */ +struct bts_Uint32Rect +{ + + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** upper left component */ + uint32 x1E; + + /** upper left component */ + uint32 y1E; + + /** lower right component */ + uint32 x2E; + + /** lower right component */ + uint32 y2E; +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** size object needs when written to memory */ +uint32 bts_Uint32Rect_memSize( struct bbs_Context* cpA, + const struct bts_Uint32Rect* ptrA ); + +/** writes object to memory; returns number of bytes written */ +uint32 bts_Uint32Rect_memWrite( struct bbs_Context* cpA, + const struct bts_Uint32Rect* ptrA, + uint16* memPtrA ); + +/** reads object from memory; returns number of bytes read */ +uint32 bts_Uint32Rect_memRead( struct bbs_Context* cpA, + struct bts_Uint32Rect* ptrA, + const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + + +#endif /* bts_UINT32RECT_EM_H */ + diff --git a/Embedded/common/src/b_TensorEm/VectorMap.c b/Embedded/common/src/b_TensorEm/VectorMap.c new file mode 100644 index 0000000..c641c15 --- /dev/null +++ b/Embedded/common/src/b_TensorEm/VectorMap.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Functions.h" +#include "b_TensorEm/VectorMap.h" + +#include "b_TensorEm/MapSequence.h" +#include "b_TensorEm/Normalizer.h" +#include "b_TensorEm/Alt.h" +#include "b_TensorEm/Mat.h" +#include "b_TensorEm/SubVecMap.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ auxiliary functions } ---------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ constructor / destructor } ----------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_VectorMap_init( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA ) +{ + ptrA->typeE = 0; + ptrA->vpMapE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +void bts_VectorMap_exit( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA ) +{ + ptrA->typeE = 0; + ptrA->vpMapE = NULL; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ operators } -------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_VectorMap_copy( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + const struct bts_VectorMap* srcPtrA ) +{ + ptrA->typeE = srcPtrA->typeE; + ptrA->vpMapE = srcPtrA->vpMapE; +} + +/* ------------------------------------------------------------------------- */ + +flag bts_VectorMap_equal( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_VectorMap* srcPtrA ) +{ + + if( ptrA->typeE != srcPtrA->typeE ) return FALSE; + if( ptrA->vpMapE != srcPtrA->vpMapE ) return FALSE; + return TRUE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ query functions } -------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ modify functions } ------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ I/O } -------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +uint32 bts_VectorMap_memSize( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA ) +{ + uint32 memSizeL = 0; + memSizeL += bbs_SIZEOF16( ptrA->typeE ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_VectorMap_memWrite( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + uint16* memPtrA ) +{ + uint32 memSizeL = bts_VectorMap_memSize( cpA, ptrA ); + memPtrA += bbs_memWrite32( &ptrA->typeE, memPtrA ); + return memSizeL; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_VectorMap_memRead( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + const uint16* memPtrA ) +{ + if( bbs_Context_error( cpA ) ) return 0; + memPtrA += bbs_memRead32( &ptrA->typeE, memPtrA ); + return bts_VectorMap_memSize( cpA, ptrA ); +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- \ghd{ exec functions } --------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void bts_vectorMapInit( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + enum bts_VectorMapType typeA ) +{ + switch( typeA ) + { + case bts_VM_MAP_SEQUENCE: bts_MapSequence_init( cpA, ( struct bts_MapSequence* )ptrA ); return; + case bts_VM_NORMALIZER: bts_Normalizer_init( cpA, ( struct bts_Normalizer* )ptrA ); return; + case bts_VM_MAT: bts_Mat_init( cpA, ( struct bts_Mat* )ptrA ); return; + case bts_VM_ALT: bts_Alt_init( cpA, ( struct bts_Alt* )ptrA ); return; + case bts_VM_SUB_VEC_MAP: bts_SubVecMap_init( cpA, ( struct bts_SubVecMap* )ptrA ); return; + + default: bbs_ERROR0( "bts_vectorMapInit: invalid type" ); + } +} + +/* ------------------------------------------------------------------------- */ + +void bts_vectorMapExit( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA ) +{ + switch( ptrA->typeE ) + { + case bts_VM_MAP_SEQUENCE: bts_MapSequence_exit( cpA, ( struct bts_MapSequence* )ptrA ); return; + case bts_VM_NORMALIZER: bts_Normalizer_exit( cpA, ( struct bts_Normalizer* )ptrA ); return; + case bts_VM_MAT: bts_Mat_exit( cpA, ( struct bts_Mat* )ptrA ); return; + case bts_VM_ALT: bts_Alt_exit( cpA, ( struct bts_Alt* )ptrA ); return; + case bts_VM_SUB_VEC_MAP: bts_SubVecMap_exit( cpA, ( struct bts_SubVecMap* )ptrA ); return; + + default: bbs_ERROR0( "bts_vectorMapExit: invalid type" ); + } +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_vectorMapMemSize( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA ) +{ + switch( ptrA->typeE ) + { + case bts_VM_MAP_SEQUENCE: return bts_MapSequence_memSize( cpA, ( struct bts_MapSequence* )ptrA ); + case bts_VM_NORMALIZER: return bts_Normalizer_memSize( cpA, ( struct bts_Normalizer* )ptrA ); + case bts_VM_MAT: return bts_Mat_memSize( cpA, ( struct bts_Mat* )ptrA ); + case bts_VM_ALT: return bts_Alt_memSize( cpA, ( struct bts_Alt* )ptrA ); + case bts_VM_SUB_VEC_MAP: return bts_SubVecMap_memSize( cpA, ( struct bts_SubVecMap* )ptrA ); + + default: bbs_ERROR0( "bts_vectorMapExit: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_vectorMapMemWrite( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, uint16* memPtrA ) +{ + switch( ptrA->typeE ) + { + case bts_VM_MAP_SEQUENCE: return bts_MapSequence_memWrite( cpA, ( struct bts_MapSequence* )ptrA, memPtrA ); + case bts_VM_NORMALIZER: return bts_Normalizer_memWrite( cpA, ( struct bts_Normalizer* )ptrA, memPtrA ); + case bts_VM_MAT: return bts_Mat_memWrite( cpA, ( struct bts_Mat* )ptrA, memPtrA ); + case bts_VM_ALT: return bts_Alt_memWrite( cpA, ( struct bts_Alt* )ptrA, memPtrA ); + case bts_VM_SUB_VEC_MAP: return bts_SubVecMap_memWrite( cpA, ( struct bts_SubVecMap* )ptrA, memPtrA ); + + default: bbs_ERROR0( "bts_vectorMapMemWrite: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_vectorMapMemRead( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ) +{ + switch( ptrA->typeE ) + { + case bts_VM_MAP_SEQUENCE: return bts_MapSequence_memRead( cpA, ( struct bts_MapSequence* )ptrA, memPtrA, mtpA ); + case bts_VM_NORMALIZER: return bts_Normalizer_memRead( cpA, ( struct bts_Normalizer* )ptrA, memPtrA, mtpA ); + case bts_VM_MAT: return bts_Mat_memRead( cpA, ( struct bts_Mat* )ptrA, memPtrA, mtpA ); + case bts_VM_ALT: return bts_Alt_memRead( cpA, ( struct bts_Alt* )ptrA, memPtrA, mtpA ); + case bts_VM_SUB_VEC_MAP: return bts_SubVecMap_memRead( cpA, ( struct bts_SubVecMap* )ptrA, memPtrA, mtpA ); + + default: bbs_ERROR0( "bts_vectorMapMemRead: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +uint32 bts_vectorMapSizeOf16( struct bbs_Context* cpA, enum bts_VectorMapType typeA ) +{ + switch( typeA ) + { + case bts_VM_MAP_SEQUENCE: return bbs_SIZEOF16( struct bts_MapSequence ); + case bts_VM_NORMALIZER: return bbs_SIZEOF16( struct bts_Normalizer ); + case bts_VM_MAT: return bbs_SIZEOF16( struct bts_Mat ); + case bts_VM_ALT: return bbs_SIZEOF16( struct bts_Alt ); + case bts_VM_SUB_VEC_MAP: return bbs_SIZEOF16( struct bts_SubVecMap ); + + default: bbs_ERROR0( "bts_vectorMapSizeOf16: invalid type" ); + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ + diff --git a/Embedded/common/src/b_TensorEm/VectorMap.h b/Embedded/common/src/b_TensorEm/VectorMap.h new file mode 100644 index 0000000..7dbec9e --- /dev/null +++ b/Embedded/common/src/b_TensorEm/VectorMap.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef bts_VECTOR_MAP_EM_H +#define bts_VECTOR_MAP_EM_H + +/* ---- includes ----------------------------------------------------------- */ + +#include "b_BasicEm/Context.h" +#include "b_BasicEm/Basic.h" +#include "b_BasicEm/MemTbl.h" +#include "b_TensorEm/Flt16Vec.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** Object Type */ +enum bts_VectorMapType +{ + bts_VM_UNDEFINED = 0, + bts_VM_MAP_SEQUENCE, /* sequence of vector maps */ + bts_VM_NORMALIZER, /* normalizes a vector using euclidean norm */ + bts_VM_MAT, /* linear transformation (matrix) */ + bts_VM_ALT, /* affine linear transformation */ + bts_VM_SUB_VEC_MAP /* sub vector extraction */ +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- object definition -------------------------------------------------- */ + +/** base object for vector maps (occurs as first element in all vector map objects) */ +struct bts_VectorMap +{ + /* ---- private data --------------------------------------------------- */ + + /* ---- public data ---------------------------------------------------- */ + + /** vector map type */ + uint32 typeE; + + /* ---- virtual functions ---------------------------------------------- */ + + /** vector map operation. + * Maps vector inVec to outVec (overflow-safe) + * Memory areas of vectors may not overlap + */ + void ( *vpMapE )( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_Flt16Vec* inVecPtrA, + struct bts_Flt16Vec* outVecPtrA ); + +}; + +/* ---- associated objects ------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +/* ---- \ghd{ constructor/destructor } ------------------------------------- */ + +/** initializes bts_VectorMap */ +void bts_VectorMap_init( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA ); + +/** resets bts_VectorMap */ +void bts_VectorMap_exit( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA ); + +/* ---- \ghd{ operators } -------------------------------------------------- */ + +/** copy operator */ +void bts_VectorMap_copy( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + const struct bts_VectorMap* srcPtrA ); + +/** equal operator */ +flag bts_VectorMap_equal( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, + const struct bts_VectorMap* srcPtrA ); + +/* ---- \ghd{ query functions } -------------------------------------------- */ + +/* ---- \ghd{ modify functions } ------------------------------------------- */ + +/* ---- \ghd{ memory I/O } ------------------------------------------------- */ + +/** word size (16-bit) object needs when written to memory */ +uint32 bts_VectorMap_memSize( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA ); + +/** writes object to memory; returns number of words (16-bit) written */ +uint32 bts_VectorMap_memWrite( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, uint16* memPtrA ); + +/** reads object from memory; returns number of words (16-bit) read */ +uint32 bts_VectorMap_memRead( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, const uint16* memPtrA ); + +/* ---- \ghd{ exec functions } --------------------------------------------- */ + +/** virtual init function */ +void bts_vectorMapInit( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + enum bts_VectorMapType typeA ); + +/** virtual exit function */ +void bts_vectorMapExit( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA ); + +/** virtual mem size function */ +uint32 bts_vectorMapMemSize( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA ); + +/** virtual mem write function */ +uint32 bts_vectorMapMemWrite( struct bbs_Context* cpA, + const struct bts_VectorMap* ptrA, uint16* memPtrA ); + +/** virtual mem read function */ +uint32 bts_vectorMapMemRead( struct bbs_Context* cpA, + struct bts_VectorMap* ptrA, + const uint16* memPtrA, + struct bbs_MemTbl* mtpA ); + +/** virtual sizeof operator for 16bit units */ +uint32 bts_vectorMapSizeOf16( struct bbs_Context* cpA, enum bts_VectorMapType typeA ); + +#endif /* bts_VECTOR_MAP_EM_H */ + diff --git a/FaceDetector_jni.cpp b/FaceDetector_jni.cpp new file mode 100644 index 0000000..a4ceeec --- /dev/null +++ b/FaceDetector_jni.cpp @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> + +#include <utils/misc.h> +#include <utils/String8.h> +#include <utils/Log.h> + +#include <core/SkBitmap.h> + +#include "jni.h" +#include "JNIHelp.h" +#include "android_runtime/AndroidRuntime.h" + +using namespace android; + +extern "C" +{ + #include <fd_emb_sdk.h> +} + +struct FaceData +{ + float confidence; + float midpointx; + float midpointy; + float eyedist; +}; + +struct FaceOffsets +{ + jfieldID confidence; + jfieldID midpointx; + jfieldID midpointy; + jfieldID eyedist; + jfieldID eulerx; + jfieldID eulery; + jfieldID eulerz; +} gFaceOffsets; + +struct FaceDetectorOffsets +{ + jfieldID fd; + jfieldID sdk; + jfieldID dcr; + jfieldID width; + jfieldID height; + jfieldID maxFaces; + jfieldID bwbuffer; +} gFaceDetectorOffsets; + +jfieldID nativeBitmapID; + +// --------------------------------------------------------------------------- + +static void getFaceData(btk_HDCR hdcr, FaceData* fdata) +{ + btk_Node leftEye, rightEye; + + btk_DCR_getNode(hdcr, 0, &leftEye); + btk_DCR_getNode(hdcr, 1, &rightEye); + + fdata->eyedist = (float)(rightEye.x - leftEye.x) / (1 << 16); + fdata->midpointx = (float)(rightEye.x + leftEye.x) / (1 << 17); + fdata->midpointy = (float)(rightEye.y + leftEye.y) / (1 << 17); + fdata->confidence = (float)btk_DCR_confidence(hdcr) / (1 << 24); +} + +// --------------------------------------------------------------------------- + +static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) +{ + jclass npeClazz = env->FindClass(exc); + env->ThrowNew(npeClazz, msg); +} + +static void +nativeClassInit +(JNIEnv *_env, jclass _this) +{ + gFaceDetectorOffsets.fd = _env->GetFieldID(_this, "mFD", "I"); + gFaceDetectorOffsets.sdk = _env->GetFieldID(_this, "mSDK", "I"); + gFaceDetectorOffsets.dcr = _env->GetFieldID(_this, "mDCR", "I"); + gFaceDetectorOffsets.width = _env->GetFieldID(_this, "mWidth", "I"); + gFaceDetectorOffsets.height = _env->GetFieldID(_this, "mHeight", "I"); + gFaceDetectorOffsets.maxFaces = _env->GetFieldID(_this, "mMaxFaces", "I"); + gFaceDetectorOffsets.bwbuffer = _env->GetFieldID(_this, "mBWBuffer", "[B"); + + jclass faceClass = _env->FindClass("android/media/FaceDetector$Face"); + gFaceOffsets.confidence = _env->GetFieldID(faceClass, "mConfidence", "F"); + gFaceOffsets.midpointx = _env->GetFieldID(faceClass, "mMidPointX", "F"); + gFaceOffsets.midpointy = _env->GetFieldID(faceClass, "mMidPointY", "F"); + gFaceOffsets.eyedist = _env->GetFieldID(faceClass, "mEyesDist", "F"); + gFaceOffsets.eulerx = _env->GetFieldID(faceClass, "mPoseEulerX", "F"); + gFaceOffsets.eulery = _env->GetFieldID(faceClass, "mPoseEulerY", "F"); + gFaceOffsets.eulerz = _env->GetFieldID(faceClass, "mPoseEulerZ", "F"); + + jclass bitmapClass = _env->FindClass("android/graphics/Bitmap"); + nativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); +} + +// --------------------------------------------------------------------------- + +static jint +initialize(JNIEnv *_env, jobject _this, + jint w, jint h, jint maxFaces) +{ + // load the configuration file + const char* root = getenv("ANDROID_ROOT"); + String8 path(root); + path.appendPath("usr/share/bmd/RFFstd_501.bmd"); + // path.appendPath("usr/share/bmd/RFFspeed_501.bmd"); + + const int MAX_FILE_SIZE = 65536; + void* initData = malloc( MAX_FILE_SIZE ); /* enough to fit entire file */ + int filedesc = open(path.string(), O_RDONLY); + int initDataSize = read(filedesc, initData, MAX_FILE_SIZE); + close(filedesc); + + // -------------------------------------------------------------------- + btk_HSDK sdk = NULL; + btk_SDKCreateParam sdkParam = btk_SDK_defaultParam(); + sdkParam.fpMalloc = malloc; + sdkParam.fpFree = free; + sdkParam.maxImageWidth = w; + sdkParam.maxImageHeight = h; + + btk_Status status = btk_SDK_create(&sdkParam, &sdk); + // make sure everything went well + if (status != btk_STATUS_OK) { + // XXX: be more precise about what went wrong + doThrow(_env, "java/lang/OutOfMemoryError", NULL); + return 0; + } + + btk_HDCR dcr = NULL; + btk_DCRCreateParam dcrParam = btk_DCR_defaultParam(); + btk_DCR_create( sdk, &dcrParam, &dcr ); + + btk_HFaceFinder fd = NULL; + btk_FaceFinderCreateParam fdParam = btk_FaceFinder_defaultParam(); + fdParam.pModuleParam = initData; + fdParam.moduleParamSize = initDataSize; + fdParam.maxDetectableFaces = maxFaces; + status = btk_FaceFinder_create( sdk, &fdParam, &fd ); + btk_FaceFinder_setRange(fd, 20, w/2); /* set eye distance range */ + + // make sure everything went well + if (status != btk_STATUS_OK) { + // XXX: be more precise about what went wrong + doThrow(_env, "java/lang/OutOfMemoryError", NULL); + return 0; + } + + // free the configuration file + free(initData); + + // initialize the java object + _env->SetIntField(_this, gFaceDetectorOffsets.fd, (jint)fd); + _env->SetIntField(_this, gFaceDetectorOffsets.sdk, (jint)sdk); + _env->SetIntField(_this, gFaceDetectorOffsets.dcr, (jint)dcr); + + return 1; +} + +static void +destroy(JNIEnv *_env, jobject _this) +{ + btk_HFaceFinder hfd = + (btk_HFaceFinder)(_env->GetIntField(_this, gFaceDetectorOffsets.fd)); + btk_FaceFinder_close( hfd ); + + btk_HDCR hdcr = (btk_HDCR)(_env->GetIntField(_this, gFaceDetectorOffsets.dcr)); + btk_DCR_close( hdcr ); + + btk_HSDK hsdk = (btk_HSDK)(_env->GetIntField(_this, gFaceDetectorOffsets.sdk)); + btk_SDK_close( hsdk ); +} + +static jint +detect(JNIEnv *_env, jobject _this, + jobject bitmap) +{ + // get the fields we need + btk_HDCR hdcr = (btk_HDCR)(_env->GetIntField(_this, gFaceDetectorOffsets.dcr)); + btk_HFaceFinder hfd = + (btk_HFaceFinder)(_env->GetIntField(_this, gFaceDetectorOffsets.fd)); + u32 maxFaces = _env->GetIntField(_this, gFaceDetectorOffsets.maxFaces); + u32 width = _env->GetIntField(_this, gFaceDetectorOffsets.width); + u32 height = _env->GetIntField(_this, gFaceDetectorOffsets.height); + + jbyteArray bwbufferObject = (jbyteArray) + _env->GetObjectField(_this, gFaceDetectorOffsets.bwbuffer); + + // get to the native bitmap + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetIntField(bitmap, nativeBitmapID); + + // get to our BW temporary buffer + jbyte* bwbuffer = _env->GetByteArrayElements(bwbufferObject, 0); + + // convert the image to B/W + uint8_t* dst = (uint8_t*)bwbuffer; + + // manage the life-time of locking our pixels + SkAutoLockPixels alp(*nativeBitmap); + + uint16_t const* src = (uint16_t const*)nativeBitmap->getPixels(); + int wpr = nativeBitmap->rowBytes() / 2; + for (u32 y=0 ; y<height; y++) { + for (u32 x=0 ; x<width ; x++) { + uint16_t rgb = src[x]; + int r = rgb >> 11; + int g2 = (rgb >> 5) & 0x3F; + int b = rgb & 0x1F; + // L coefficients 0.299 0.587 0.11 + int L = (r<<1) + (g2<<1) + (g2>>1) + b; + *dst++ = L; + } + src += wpr; + } + + // run detection + btk_DCR_assignGrayByteImage(hdcr, bwbuffer, width, height); + + int numberOfFaces = 0; + if (btk_FaceFinder_putDCR(hfd, hdcr) == btk_STATUS_OK) { + numberOfFaces = btk_FaceFinder_faces(hfd); + } + + // release the arrays we're using + _env->ReleaseByteArrayElements(bwbufferObject, bwbuffer, 0); + return numberOfFaces; +} + +static void +get_face(JNIEnv *_env, jobject _this, + jobject face, jint index) +{ + btk_HDCR hdcr = (btk_HDCR)(_env->GetIntField(_this, gFaceDetectorOffsets.dcr)); + btk_HFaceFinder hfd = + (btk_HFaceFinder)(_env->GetIntField(_this, gFaceDetectorOffsets.fd)); + + FaceData faceData; + btk_FaceFinder_getDCR(hfd, hdcr); + getFaceData(hdcr, &faceData); + + const float X2F = 1.0f / 65536.0f; + _env->SetFloatField(face, gFaceOffsets.confidence, faceData.confidence); + _env->SetFloatField(face, gFaceOffsets.midpointx, faceData.midpointx); + _env->SetFloatField(face, gFaceOffsets.midpointy, faceData.midpointy); + _env->SetFloatField(face, gFaceOffsets.eyedist, faceData.eyedist); + _env->SetFloatField(face, gFaceOffsets.eulerx, 0); + _env->SetFloatField(face, gFaceOffsets.eulery, 0); + _env->SetFloatField(face, gFaceOffsets.eulerz, 0); +} + +// --------------------------------------------------------------------------- + +static const char *classPathName = "android/media/FaceDetector"; + +static JNINativeMethod methods[] = { +{"nativeClassInit", "()V", (void*)nativeClassInit }, +{"fft_initialize", "(III)I", (void*)initialize }, +{"fft_detect", "(Landroid/graphics/Bitmap;)I", (void*)detect }, +{"fft_get_face", "(Landroid/media/FaceDetector$Face;I)V",(void*)get_face }, +{"fft_destroy", "()V", (void*)destroy }, +}; + +int register_android_media_FaceDetector(JNIEnv *_env) +{ + return android::AndroidRuntime::registerNativeMethods( + _env, classPathName, methods, NELEM(methods)); +} + +// --------------------------------------------------------------------------- + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + JNIEnv* env = NULL; + jint result = -1; + + if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + LOGE("ERROR: GetEnv failed\n"); + goto bail; + } + assert(env != NULL); + + if (register_android_media_FaceDetector(env) < 0) { + LOGE("ERROR: MediaPlayer native registration failed\n"); + goto bail; + } + + /* success -- return valid version number */ + result = JNI_VERSION_1_4; + +bail: + return result; +} diff --git a/FaceRecEm/common/src/b_FDSDK/DCR.c b/FaceRecEm/common/src/b_FDSDK/DCR.c new file mode 100644 index 0000000..1779731 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/DCR.c @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "DCR_Internal.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- functions ---------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void btk_DCR_init( struct bbs_Context* cpA, struct btk_DCR* ptrA ) +{ + ptrA->hsdkE = NULL; + ptrA->hidE = btk_HID_DCR; + bpi_DCR_init( cpA, &ptrA->dcrE ); +} + +/* ------------------------------------------------------------------------- */ + +void btk_DCR_exit( struct bbs_Context* cpA, struct btk_DCR* ptrA ) +{ + ptrA->hsdkE = NULL; + ptrA->hidE = btk_HID_DCR; + bpi_DCR_exit( cpA, &ptrA->dcrE ); +} + +/* ------------------------------------------------------------------------- */ + +btk_DCRCreateParam btk_DCR_defaultParam() +{ + btk_DCRCreateParam paramL; + paramL.reserved = 0; + return paramL; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_create( btk_HSDK hsdkA, + const btk_DCRCreateParam* pCreateParamA, + btk_HDCR* hpdcrA ) +{ + btk_HDCR hdcrL = NULL; + + if( hpdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( *hpdcrA != NULL ) return btk_STATUS_INVALID_HANDLE; + if( hsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; + if( pCreateParamA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + hdcrL = ( btk_HDCR )bbs_MemSeg_alloc( &hsdkA->contextE, hsdkA->contextE.memTblE.espArrE[ 0 ], bbs_SIZEOF16( struct btk_DCR ) ); + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; + + btk_DCR_init( &hsdkA->contextE, hdcrL ); + hdcrL->hsdkE = hsdkA; + + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; + + bpi_DCR_create( &hsdkA->contextE, + &hdcrL->dcrE, + hsdkA->maxImageWidthE, + hsdkA->maxImageHeightE, +#ifdef btk_FRSDK + 6000 >> 1, +#else + 0, +#endif + &hsdkA->contextE.memTblE ); + + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; + + *hpdcrA = hdcrL; + hsdkA->refCtrE++; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_close( btk_HDCR hdcrA ) +{ + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA->hsdkE == NULL ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hdcrA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + hsdkL->refCtrE--; + + btk_DCR_exit( &hsdkL->contextE, hdcrA ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + bbs_MemSeg_free( &hsdkL->contextE, hsdkL->contextE.memTblE.espArrE[ 0 ], hdcrA ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_assignGrayByteImage( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA ) +{ + return btk_DCR_assignImage( hdcrA, pDataA, widthA, heightA ); +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_assignImage( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA ) +{ + const char* fNameL = "btk_DCR_assignImage"; + + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hdcrA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( pDataA == NULL ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image references inavlid memory", fNameL ) ); + + return btk_STATUS_ERROR; + } + + if( widthA == 0 || heightA == 0 ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image has size 0", fNameL ) ); + + return btk_STATUS_ERROR; + } + + bpi_DCR_assignGrayByteImage( &hsdkL->contextE, &hdcrA->dcrE, pDataA, widthA, heightA ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_assignGrayByteImageROI( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA, + const btk_Rect* pRectA ) +{ + return btk_DCR_assignImageROI( hdcrA, pDataA, widthA, heightA, pRectA ); +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_assignImageROI( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA, + const btk_Rect* pRectA ) +{ + const char* fNameL = "btk_DCR_assignGrayByteImageROI"; + + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hdcrA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( pDataA == NULL ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image references invalid memory", fNameL ) ); + return btk_STATUS_ERROR; + } + + if( widthA == 0 || heightA == 0 ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image has size 0", fNameL ) ); + return btk_STATUS_ERROR; + } + + if( pRectA == NULL ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned ROI rectangle references invalid memory", fNameL ) ); + return btk_STATUS_ERROR; + } + + if( pRectA->xMax <= pRectA->xMin || pRectA->yMax <= pRectA->yMin ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned ROI rectangle is inverted (max<min) or zero", fNameL ) ); + return btk_STATUS_ERROR; + } + + { + struct bts_Int16Rect rectL; + rectL = bts_Int16Rect_create( pRectA->xMin >> 16, + pRectA->yMin >> 16, + pRectA->xMax >> 16, + pRectA->yMax >> 16 ); + + /* rect must stay within image boundaries - adjust coordinates if necessary */ + rectL.x1E = rectL.x1E < 0 ? 0 : rectL.x1E; + rectL.y1E = rectL.y1E < 0 ? 0 : rectL.y1E; + rectL.x2E = rectL.x2E > ( int32 )widthA ? widthA : rectL.x2E; + rectL.y2E = rectL.y2E > ( int32 )heightA ? heightA : rectL.y2E; + + bpi_DCR_assignGrayByteImageROI( &hsdkL->contextE, &hdcrA->dcrE, pDataA, widthA, heightA, &rectL ); + } + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +u32 btk_DCR_nodeCount( btk_HDCR hdcrA ) +{ + if( hdcrA == NULL ) return 0; + if( hdcrA->hidE != btk_HID_DCR ) return 0; + return hdcrA->dcrE.sdkClusterE.clusterE.sizeE; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_getNode( btk_HDCR hdcrA, + u32 indexA, + btk_Node* nodePtrA ) +{ + const char* fNameL = "btk_DCR_getNode"; + + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hdcrA->hsdkE; + if( nodePtrA == NULL ) return btk_STATUS_INVALID_HANDLE; + + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( indexA >= hdcrA->dcrE.sdkClusterE.clusterE.sizeE ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nIndex is out of range", fNameL ) ); + return btk_STATUS_ERROR; + } + + nodePtrA->id = hdcrA->dcrE.sdkClusterE.idArrE.arrPtrE[ indexA ]; + nodePtrA->x = ( ( s16p16 )hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ indexA ].xE ) << ( 16 - hdcrA->dcrE.sdkClusterE.clusterE.bbpE ); + nodePtrA->y = ( ( s16p16 )hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ indexA ].yE ) << ( 16 - hdcrA->dcrE.sdkClusterE.clusterE.bbpE ); + if( hdcrA->dcrE.roiRectE.x1E > 0 ) nodePtrA->x += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; + if( hdcrA->dcrE.roiRectE.y1E > 0 ) nodePtrA->y += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; + nodePtrA->x += ( int32 )hdcrA->dcrE.offsE.xE << 16; + nodePtrA->y += ( int32 )hdcrA->dcrE.offsE.yE << 16; + + nodePtrA->reserved = 0; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_DCR_getRect( btk_HDCR hdcrA, + btk_Rect* pRectA ) +{ + const char* fNameL = "btk_DCR_getRect"; + + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hdcrA->hsdkE; + if( pRectA == NULL ) return btk_STATUS_INVALID_HANDLE; + + /* find eye nodes */ + { + const struct bbs_Int16Arr* pIdArrL = &hdcrA->dcrE.sdkClusterE.idArrE; + int32 lIndexL = -1; + int32 rIndexL = -1; + uint32 iL; + for( iL = 0; iL < pIdArrL->sizeE; iL++ ) + { + if( pIdArrL->arrPtrE[ iL ] == 0 ) + { + lIndexL = iL; + } + else if( pIdArrL->arrPtrE[ iL ] == 1 ) + { + rIndexL = iL; + } + } + + if( lIndexL == -1 || rIndexL == -1 ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nFace rectangle is not available", fNameL ) ); + return btk_STATUS_ERROR; + } + + { + int32 bbpL = hdcrA->dcrE.sdkClusterE.clusterE.bbpE; + int32 lxL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ lIndexL ].xE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; + int32 lyL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ lIndexL ].yE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; + int32 rxL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ rIndexL ].xE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; + int32 ryL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ rIndexL ].yE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; + int32 doffL = ( rxL - lxL ) >> 1; + + pRectA->xMin = ( lxL - doffL ) << 16; + pRectA->xMax = ( rxL + doffL ) << 16; + pRectA->yMin = ( ( ( lyL + ryL + 1 ) >> 1 ) - doffL ) << 16; + pRectA->yMax = ( pRectA->yMin + ( pRectA->xMax - pRectA->xMin ) ); + if( hdcrA->dcrE.roiRectE.x1E > 0 ) + { + pRectA->xMin += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; + pRectA->xMax += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; + } + if( hdcrA->dcrE.roiRectE.y1E > 0 ) + { + pRectA->yMin += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; + pRectA->yMax += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; + } + + pRectA->xMin += ( int32 )hdcrA->dcrE.offsE.xE << 16; + pRectA->yMin += ( int32 )hdcrA->dcrE.offsE.yE << 16; + pRectA->xMax += ( int32 )hdcrA->dcrE.offsE.xE << 16; + pRectA->yMax += ( int32 )hdcrA->dcrE.offsE.yE << 16; + + } + } + + return btk_STATUS_OK; +} + + +/* ------------------------------------------------------------------------- */ + +s8p24 btk_DCR_confidence( btk_HDCR hdcrA ) +{ + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return 0; + if( hdcrA->hidE != btk_HID_DCR ) return 0; + hsdkL = hdcrA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return 0; + + return hdcrA->dcrE.confidenceE; +} + +/* ------------------------------------------------------------------------- */ + +u32 btk_DCR_approved( btk_HDCR hdcrA ) +{ + btk_HSDK hsdkL = NULL; + if( hdcrA == NULL ) return 0; + if( hdcrA->hidE != btk_HID_DCR ) return 0; + hsdkL = hdcrA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return 0; + + return ( u32 )hdcrA->dcrE.approvedE; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/FaceRecEm/common/src/b_FDSDK/DCR.h b/FaceRecEm/common/src/b_FDSDK/DCR.h new file mode 100644 index 0000000..4fbc275 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/DCR.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_DCR_EM_H +#define btk_DCR_EM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Data Carrier object + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "SDK.h" + +/* ---- related objects --------------------------------------------------- */ + +/** data carrier object */ +struct btk_DCR; + +/* ---- typedefs ----------------------------------------------------------- */ + +/** handle for data carrier object */ +typedef struct btk_DCR* btk_HDCR; + +/** node data structure */ +typedef struct +{ + s16p16 x; /* x-coordinate */ + s16p16 y; /* y-coordinate */ + s32 id; /* node id */ + s16p16 reserved; /* reserved for future versions (0) */ +} btk_Node; + +/** rectangle data structure */ +typedef struct +{ + s16p16 xMin; /* x min coordinate */ + s16p16 yMin; /* y min coordinate */ + s16p16 xMax; /* x max coordinate */ + s16p16 yMax; /* y max coordinate */ +} btk_Rect; + +/** DCR creation parameters */ +typedef struct +{ + /* reserved parameter (0) */ + u32 reserved; + +} btk_DCRCreateParam; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- functions ---------------------------------------------------------- */ + +/** returns default data carrier parameters */ +btk_DECLSPEC +btk_DCRCreateParam btk_DCR_defaultParam( void ); + +/** creates a data carrier object */ +btk_DECLSPEC +btk_Status btk_DCR_create( btk_HSDK hsdkA, + const btk_DCRCreateParam* pCreateParamA, + btk_HDCR* hpdcrA ); + +/** closes a data carrier object */ +btk_DECLSPEC +btk_Status btk_DCR_close( btk_HDCR hdcrA ); + +/** deprecated (use assignImage) */ +btk_DECLSPEC +btk_Status btk_DCR_assignGrayByteImage( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA ); + +/** assigns a byte gray image referenced by pDataA to the data carrier */ +btk_DECLSPEC +btk_Status btk_DCR_assignImage( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA ); + +/** deprecated (use assignImageROI) */ +btk_DECLSPEC +btk_Status btk_DCR_assignGrayByteImageROI( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA, + const btk_Rect* pRectA ); + +/** assigns a byte gray image referenced by pDataA to the data carrier and + * a region of interest given by pRectA. + */ +btk_DECLSPEC +btk_Status btk_DCR_assignImageROI( btk_HDCR hdcrA, + const void* pDataA, + u32 widthA, + u32 heightA, + const btk_Rect* pRectA ); + +/** extracts facial rectangle */ +btk_DECLSPEC +btk_Status btk_DCR_getRect( btk_HDCR hdcrA, + btk_Rect* pRectA ); + +/** returns number of available landmark nodes */ +btk_DECLSPEC +u32 btk_DCR_nodeCount( btk_HDCR hdcrA ); + +/** extracts information about indexed node */ +btk_DECLSPEC +btk_Status btk_DCR_getNode( btk_HDCR hdcrA, + u32 indexA, + btk_Node* pNodeA ); + +/** returns confidence 8.24 fixed format */ +btk_DECLSPEC +s8p24 btk_DCR_confidence( btk_HDCR hdcrA ); + +/** returns approval flag (0=false; 1=true)*/ +btk_DECLSPEC +u32 btk_DCR_approved( btk_HDCR hdcrA ); + + +#ifdef __cplusplus +} +#endif + +#endif /* btk_DCR_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/DCR_Internal.h b/FaceRecEm/common/src/b_FDSDK/DCR_Internal.h new file mode 100644 index 0000000..0e848cb --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/DCR_Internal.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_DCR_Internal_EM_H +#define btk_DCR_Internal_EM_H + +/** + * DCR object + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "DCR.h" +#include "SDK_Internal.h" +#include "b_APIEm/DCR.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** data carrier object */ +struct btk_DCR +{ + /** SDK context handle */ + btk_HSDK hsdkE; + + /** handle id */ + btk_HandleId hidE; + + /** API DCR */ + struct bpi_DCR dcrE; +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- functions ---------------------------------------------------------- */ + +#endif /* btk_DCR_Internal_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/FaceFinder.c b/FaceRecEm/common/src/b_FDSDK/FaceFinder.c new file mode 100644 index 0000000..b24ac11 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/FaceFinder.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "FaceFinder_Internal.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/* ---- constants ---------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- functions ---------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void btk_FaceFinder_init( struct bbs_Context* cpA, struct btk_FaceFinder* ptrA ) +{ + ptrA->hsdkE = NULL; + ptrA->hidE = btk_HID_FF; + + bpi_FaceFinderRef_init( cpA, &ptrA->ffE ); + + ptrA->facesE = 0; + ptrA->faceIndexE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void btk_FaceFinder_exit( struct bbs_Context* cpA, struct btk_FaceFinder* ptrA ) +{ + ptrA->hsdkE = NULL; + ptrA->hidE = btk_HID_FF; + + bpi_FaceFinderRef_exit( cpA, &ptrA->ffE ); + + ptrA->facesE = 0; + ptrA->faceIndexE = 0; +} + +/* ------------------------------------------------------------------------- */ + +btk_FaceFinderCreateParam btk_FaceFinder_defaultParam() +{ + btk_FaceFinderCreateParam paramL; + paramL.reserved = 0; + paramL.pModuleParam = NULL; + paramL.moduleParamSize = 0; + paramL.maxDetectableFaces = 0; + return paramL; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_FaceFinder_create( btk_HSDK hsdkA, /* sdk handle */ + const btk_FaceFinderCreateParam* pCreateParamA, + btk_HFaceFinder* hpFaceFinderA ) +{ + const char* fNameL = "btk_FaceFinder_create"; + + btk_HFaceFinder hFaceFinderL = NULL; + + if( hpFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( *hpFaceFinderA != NULL ) return btk_STATUS_INVALID_HANDLE; + if( hsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; + if( pCreateParamA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + hFaceFinderL = ( btk_HFaceFinder )bbs_MemSeg_alloc( &hsdkA->contextE, hsdkA->contextE.memTblE.espArrE[ 0 ], bbs_SIZEOF16( struct btk_FaceFinder ) ); + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; + + btk_FaceFinder_init( &hsdkA->contextE, hFaceFinderL ); + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; + + hFaceFinderL->hsdkE = hsdkA; + + if( btk_SDK_paramConsistencyTest( hsdkA, pCreateParamA->pModuleParam, pCreateParamA->moduleParamSize, fNameL ) == btk_STATUS_ERROR ) return btk_STATUS_ERROR; + + if( hsdkA->maxImageWidthE * hsdkA->maxImageHeightE == 0 ) + { + bbs_Context_pushError( &hsdkA->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nSDK parameter maxImageWidth or maxImageWidth is 0!\n" + "Since SDK version 1.3.0 the maximum image size must be specified when creating the SDK handle.\n" + "Set the values in *pCreateParamA when you call function btk_SDK_create.", fNameL ) ); + return btk_STATUS_ERROR; + } + + bpi_FaceFinderRef_memRead( &hsdkA->contextE, + &hFaceFinderL->ffE, + hsdkA->maxImageWidthE, + hsdkA->maxImageHeightE, + pCreateParamA->pModuleParam, + &hsdkA->contextE.memTblE ); + + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; + + *hpFaceFinderA = hFaceFinderL; + hsdkA->refCtrE++; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_FaceFinder_close( btk_HFaceFinder hFaceFinderA ) +{ + btk_HSDK hsdkL = NULL; + if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; + if( hFaceFinderA->hsdkE == NULL ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hFaceFinderA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + hsdkL->refCtrE--; + + btk_FaceFinder_exit( &hsdkL->contextE, hFaceFinderA ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + bbs_MemSeg_free( &hsdkL->contextE, hsdkL->contextE.memTblE.espArrE[ 0 ], hFaceFinderA ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_FaceFinder_setRange( btk_HFaceFinder hFaceFinderA, + u32 minDistA, + u32 maxDistA ) +{ + btk_HSDK hsdkL = NULL; + if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hFaceFinderA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + bpi_FaceFinderRef_setRange( &hsdkL->contextE, &hFaceFinderA->ffE, minDistA, maxDistA ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_FaceFinder_putDCR( btk_HFaceFinder hFaceFinderA, + btk_HDCR hdcrA ) +{ + const char* fNameL = "btk_FaceFinder_putDCR"; + + btk_HSDK hsdkL = NULL; + if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hFaceFinderA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( hdcrA->dcrE.imageDataPtrE == NULL ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, + "%s:\nNo image was assigned to data carrier", fNameL ) ); + } + + hFaceFinderA->facesE = bpi_FaceFinderRef_putDcr( &hsdkL->contextE, + &hFaceFinderA->ffE, + &hdcrA->dcrE ); + + hFaceFinderA->faceIndexE = 0; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +u32 btk_FaceFinder_faces( btk_HFaceFinder hFaceFinderA ) +{ + if( hFaceFinderA == NULL ) return 0; + if( hFaceFinderA->hidE != btk_HID_FF ) return 0; + return hFaceFinderA->facesE - hFaceFinderA->faceIndexE; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_FaceFinder_getDCR( btk_HFaceFinder hFaceFinderA, + btk_HDCR hdcrA ) +{ + btk_HSDK hsdkL = NULL; + if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hFaceFinderA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( hFaceFinderA->faceIndexE < hFaceFinderA->facesE ) + { + bpi_FaceFinderRef_getDcr( &hsdkL->contextE, + &hFaceFinderA->ffE, + hFaceFinderA->faceIndexE, + &hdcrA->dcrE ); + + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + hdcrA->dcrE.approvedE = TRUE; + hFaceFinderA->faceIndexE++; + } + else + { + bpi_FaceFinderRef_getDcr( &hsdkL->contextE, + &hFaceFinderA->ffE, + 0, + &hdcrA->dcrE ); + hdcrA->dcrE.approvedE = FALSE; + } + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_FaceFinder_process( btk_HFaceFinder hFaceFinderA, + btk_HDCR hdcrA ) +{ + const char* fNameL = "btk_FaceFinder_process"; + int32 confL; + + btk_HSDK hsdkL = NULL; + if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; + if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; + hsdkL = hFaceFinderA->hsdkE; + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( hdcrA->dcrE.imageDataPtrE == NULL ) + { + bbs_Context_pushError( &hsdkL->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, + "%s:\nNo image was assigned to data carrier", fNameL ) ); + } + + confL = bpi_FaceFinderRef_process( &hsdkL->contextE, + &hFaceFinderA->ffE, + &hdcrA->dcrE ); + + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + hdcrA->dcrE.confidenceE = confL; + hdcrA->dcrE.approvedE = confL > ( ( int32 )1 << 23 ); + + hFaceFinderA->faceIndexE = 0; + hFaceFinderA->facesE = 0; + + bts_IdCluster2D_copy( &hsdkL->contextE, + &hdcrA->dcrE.sdkClusterE, + &hdcrA->dcrE.mainClusterE ); + + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/FaceRecEm/common/src/b_FDSDK/FaceFinder.h b/FaceRecEm/common/src/b_FDSDK/FaceFinder.h new file mode 100644 index 0000000..02d4d1a --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/FaceFinder.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_FaceFinder_EM_H +#define btk_FaceFinder_EM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Face Finder object + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "DCR.h" + +/* ---- related objects --------------------------------------------------- */ + +/** face finder object */ +struct btk_FaceFinder; + +/* ---- typedefs ----------------------------------------------------------- */ + +/** handle for face finder object */ +typedef struct btk_FaceFinder* btk_HFaceFinder; + +/** FaceFinder creation parameters */ +typedef struct +{ + /* reserved parameter */ + u32 reserved; + + /* obaque module parameters */ + void* pModuleParam; + + /* size of module parameters */ + u32 moduleParamSize; + + /* maximum number of detectable faces */ + u32 maxDetectableFaces; + +} btk_FaceFinderCreateParam; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- functions ---------------------------------------------------------- */ + +/** returns default FaceFinder parameters */ +btk_DECLSPEC +btk_FaceFinderCreateParam btk_FaceFinder_defaultParam( void ); + +/** creates a face finder object */ +btk_DECLSPEC +btk_Status btk_FaceFinder_create( btk_HSDK hsdkA, /* sdk handle */ + const btk_FaceFinderCreateParam* pCreateParamA, + btk_HFaceFinder* hpFaceFinderA ); + +/** closes a face finder object */ +btk_DECLSPEC +btk_Status btk_FaceFinder_close( btk_HFaceFinder hFaceFinderA ); + +/** sets eye distance range */ +btk_DECLSPEC +btk_Status btk_FaceFinder_setRange( btk_HFaceFinder hFaceFinderA, + u32 minDistA, + u32 maxDistA ); + +/** passes a DCR object and triggers image processing */ +btk_DECLSPEC +btk_Status btk_FaceFinder_putDCR( btk_HFaceFinder hFaceFinderA, + btk_HDCR hdcrA ); + +/** returns number of faces that can be retrieved from face finder with function btk_FaceFinder_getDCR */ +btk_DECLSPEC +u32 btk_FaceFinder_faces( btk_HFaceFinder hFaceFinderA ); + +/** retrieves a DCR object for each detected face */ +btk_DECLSPEC +btk_Status btk_FaceFinder_getDCR( btk_HFaceFinder hFaceFinderA, + btk_HDCR hdcrA ); + +/** processes DCR for single face detection */ +btk_DECLSPEC +btk_Status btk_FaceFinder_process( btk_HFaceFinder hFaceFinderA, + btk_HDCR hdcrA ); + +#ifdef __cplusplus +} +#endif + +#endif /* btk_FaceFinder_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/FaceFinder_Internal.h b/FaceRecEm/common/src/b_FDSDK/FaceFinder_Internal.h new file mode 100644 index 0000000..02eb3d3 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/FaceFinder_Internal.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_FaceFinder_Internal_EM_H +#define btk_FaceFinder_Internal_EM_H + +/** + * FaceFinder object + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "FaceFinder.h" +#include "DCR_Internal.h" +#include "b_APIEm/FaceFinderRef.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** face finder object */ +struct btk_FaceFinder +{ + /** SDK context handle */ + btk_HSDK hsdkE; + + /** handle id */ + btk_HandleId hidE; + + /** internal module */ + struct bpi_FaceFinderRef ffE; + + /** number of available faces */ + uint32 facesE; + + /** index into face - array */ + uint32 faceIndexE; +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- functions ---------------------------------------------------------- */ + +#endif /* btk_FaceFinder_Internal_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/SDK.c b/FaceRecEm/common/src/b_FDSDK/SDK.c new file mode 100644 index 0000000..7085bf3 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/SDK.c @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "SDK_Internal.h" +#include "b_BasicEm/Functions.h" + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ +/* */ +/* ---- functions ---------------------------------------------------------- */ +/* */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ + +void btk_SDK_init( struct btk_SDK* ptrA ) +{ + bbs_Context_init( &ptrA->contextE ); + ptrA->hidE = btk_HID_SDK; + ptrA->refCtrE = 0; + ptrA->mallocFPtrE = NULL; + ptrA->freeFPtrE = NULL; + ptrA->errorFPtrE = NULL; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +void btk_SDK_exit( struct btk_SDK* ptrA ) +{ + bbs_Context_exit( &ptrA->contextE ); + ptrA->hidE = btk_HID_SDK; + ptrA->refCtrE = 0; + ptrA->mallocFPtrE = NULL; + ptrA->freeFPtrE = NULL; + ptrA->errorFPtrE = NULL; + ptrA->maxImageWidthE = 0; + ptrA->maxImageHeightE = 0; +} + +/* ------------------------------------------------------------------------- */ + +/* malloc wrapper */ +void* btk_malloc( struct bbs_Context* cpA, + const struct bbs_MemSeg* memSegPtrA, + uint32 sizeA ) +{ + btk_HSDK hsdkL = ( btk_HSDK )cpA; + if( hsdkL->mallocFPtrE != NULL ) + { + return hsdkL->mallocFPtrE( sizeA ); + } + else + { + return NULL; + } +} + +/* ------------------------------------------------------------------------- */ + +/** error handler wrapper */ +void btk_error( struct bbs_Context* cpA ) +{ + btk_HSDK hsdkL = ( btk_HSDK )cpA; + if( hsdkL->errorFPtrE != NULL ) + { + hsdkL->errorFPtrE( hsdkL ); + } +} + +/* ------------------------------------------------------------------------- */ + +btk_SDKCreateParam btk_SDK_defaultParam() +{ + btk_SDKCreateParam paramL; + paramL.fpError = NULL; + paramL.fpMalloc = NULL; + paramL.fpFree = NULL; + paramL.pExMem = NULL; + paramL.sizeExMem = 0; + paramL.pShMem = NULL; + paramL.sizeShMem = 0; + paramL.licenseKey = NULL; + paramL.maxImageWidth = 0; + paramL.maxImageHeight = 0; + return paramL; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_SDK_create( const btk_SDKCreateParam* pCreateParamA, + btk_HSDK* hpsdkA ) +{ + btk_HSDK hsdkL = NULL; + if( hpsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( *hpsdkA != NULL ) return btk_STATUS_INVALID_HANDLE; + + if( pCreateParamA->fpMalloc != NULL ) + { + if( pCreateParamA->fpFree == NULL ) return btk_STATUS_INVALID_HANDLE; + + /* allocate context */ + hsdkL = ( btk_HSDK )pCreateParamA->fpMalloc( bbs_SIZEOF8( struct btk_SDK ) ); + if( hsdkL == NULL ) return btk_STATUS_INVALID_HANDLE; + + btk_SDK_init( hsdkL ); + + /* initialize SDK context */ + hsdkL->mallocFPtrE = pCreateParamA->fpMalloc; + hsdkL->freeFPtrE = pCreateParamA->fpFree; + hsdkL->errorFPtrE = pCreateParamA->fpError; + + /* initialize core context */ + bbs_Context_quickInit( &hsdkL->contextE, btk_malloc, pCreateParamA->fpFree, btk_error ); + if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; + } + else + { + uint16* exMemPtrL = ( uint16* )pCreateParamA->pExMem; + uint32 exMemSizeL = pCreateParamA->sizeExMem >> 1; + + if( pCreateParamA->pExMem == NULL ) return btk_STATUS_INVALID_HANDLE; + if( pCreateParamA->pShMem == NULL ) return btk_STATUS_INVALID_HANDLE; + if( pCreateParamA->pExMem == pCreateParamA->pShMem ) return btk_STATUS_INVALID_HANDLE; + + if( pCreateParamA->sizeExMem < bbs_SIZEOF16( struct btk_SDK ) ) return btk_STATUS_INVALID_HANDLE; + + /* allocate context */ + hsdkL = ( btk_HSDK )exMemPtrL; + exMemPtrL += bbs_SIZEOF16( struct btk_SDK ); + exMemSizeL -= bbs_SIZEOF16( struct btk_SDK ); + + btk_SDK_init( hsdkL ); + + hsdkL->errorFPtrE = pCreateParamA->fpError; + hsdkL->contextE.errorHandlerE = btk_error; + + /* initialize core context */ + bbs_Context_addStaticSeg( &hsdkL->contextE, exMemPtrL, exMemSizeL, FALSE, 0 ); + bbs_Context_addStaticSeg( &hsdkL->contextE, pCreateParamA->pShMem, pCreateParamA->sizeShMem >> 1, TRUE, 0 ); + } + + hsdkL->maxImageWidthE = pCreateParamA->maxImageWidth; + hsdkL->maxImageHeightE = pCreateParamA->maxImageHeight; + + *hpsdkA = hsdkL; + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_SDK_close( btk_HSDK hsdkA ) +{ + const char* fNameL = "btk_SDK_close"; + + if( hsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; + if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; + if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; + + if( hsdkA->refCtrE > 0 ) + { + bbs_Context_pushError( &hsdkA->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nThis SDK context is still in use by %i objects!\n" + "Close all instances of the context scope first.\n", + fNameL, + hsdkA->refCtrE ) ); + + return btk_STATUS_ERROR; + } + + if( hsdkA->freeFPtrE ) + { + btk_fpFree freeFPtrL = hsdkA->freeFPtrE; + btk_SDK_exit( hsdkA ); + freeFPtrL( hsdkA ); + } + else + { + btk_SDK_exit( hsdkA ); + } + + /* btk_SDK_exit clears error stack and does not produce an error condition */ + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +btk_Error btk_SDK_getError( btk_HSDK hsdkA, char* msgBufA, u32 msgBufSizeA ) +{ + if( hsdkA == NULL ) return btk_ERR_CORRUPT_DATA; + if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; + + if( bbs_Context_error( &hsdkA->contextE ) ) + { + struct bbs_Error errL = bbs_Context_popError( &hsdkA->contextE ); + if( msgBufA != NULL ) bbs_strncpy( msgBufA, errL.textE, msgBufSizeA ); + switch( errL.errorE ) + { + case bbs_ERR_OUT_OF_MEMORY: return btk_ERR_MEMORY; + case bbs_ERR_MEMORY_OVERFLOW: return btk_ERR_MEMORY; + case bbs_ERR_WRONG_VERSION: return btk_ERR_VERSION; + case bbs_ERR_CORRUPT_DATA: return btk_ERR_CORRUPT_DATA; + default: return btk_ERR_INTERNAL; + } + } + + return btk_ERR_NO_ERROR; +} + +/* ------------------------------------------------------------------------- */ + +u32 btk_SDK_exAllocSize( btk_HSDK hsdkA ) +{ + if( hsdkA == NULL ) return 0; + if( hsdkA->hidE != btk_HID_SDK ) return 0; + return ( bbs_Context_exclAllocSize( &hsdkA->contextE, 0 ) * 2 ) + bbs_SIZEOF8( struct btk_SDK ); +} + +/* ------------------------------------------------------------------------- */ + +u32 btk_SDK_shAllocSize( btk_HSDK hsdkA ) +{ + if( hsdkA == NULL ) return 0; + if( hsdkA->hidE != btk_HID_SDK ) return 0; + return bbs_Context_shrdAllocSize( &hsdkA->contextE, 0 ) * 2; +} + +/* ------------------------------------------------------------------------- */ + +u32 btk_SDK_allocSize( btk_HSDK hsdkA ) +{ + return btk_SDK_exAllocSize( hsdkA ) + btk_SDK_shAllocSize( hsdkA ); +} + +/* ------------------------------------------------------------------------- */ + +btk_Status btk_SDK_paramConsistencyTest( struct btk_SDK* hsdkA, + const void* memPtrA, + u32 memSizeA, + const char* fNameA ) +{ + const uint16* memPtrL = ( uint16* )memPtrA; + uint32 memSizeL; + uint32 iL; + uint16 sumL = 0; + + if( memSizeA < sizeof( memSizeL ) ) + { + bbs_Context_pushError( &hsdkA->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, + "%s:\nCorrupt parameter data.", fNameA ) ); + return btk_STATUS_ERROR; + } + + memPtrL += bbs_memRead32( &memSizeL, memPtrL ); + + if( memSizeA < ( memSizeL << 1 ) ) + { + bbs_Context_pushError( &hsdkA->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, + "%s:\nCorrupt parameter data.", fNameA ) ); + return btk_STATUS_ERROR; + } + + memPtrL = ( uint16* )memPtrA; + + for( iL = 0; iL < memSizeL; iL++ ) + { + uint16 valL = 0; + memPtrL += bbs_memRead16( &valL, memPtrL ); + sumL += valL; + } + + if( sumL != 0xFFFF ) + { + bbs_Context_pushError( &hsdkA->contextE, + bbs_Error_create( bbs_ERR_ERROR, 0, NULL, + "%s:\nChecksum error; corrupt parameter data.", fNameA ) ); + return btk_STATUS_ERROR; + } + + return btk_STATUS_OK; +} + +/* ------------------------------------------------------------------------- */ + +/* ========================================================================= */ diff --git a/FaceRecEm/common/src/b_FDSDK/SDK.h b/FaceRecEm/common/src/b_FDSDK/SDK.h new file mode 100644 index 0000000..33742e5 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/SDK.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_SDK_EM_H +#define btk_SDK_EM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Visual Sensing SDK + * SDK Context object + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "Types.h" + +/* ---- related objects --------------------------------------------------- */ + +/** SDK context object */ +struct btk_SDK; + +/* ---- typedefs ----------------------------------------------------------- */ + +/** handle for SDK context */ +typedef struct btk_SDK* btk_HSDK; + +/** malloc function pointer */ +typedef void* ( *btk_fpMalloc )( u32 sizeA ); + +/** free function pointer */ +typedef void ( *btk_fpFree )( void* memPtrA ); + +/** error handler function pointer */ +typedef void ( *btk_fpError )( btk_HSDK hsdkA ); + +/** SDK creation parameters */ +typedef struct +{ + /** (optional) handler to error-handler function */ + btk_fpError fpError; + + /** handler to malloc function */ + btk_fpMalloc fpMalloc; + + /** handler to free function */ + btk_fpFree fpFree; + + /** pointer to preallocated exclusive (=persistent) memory (alternative to fpMalloc) */ + void* pExMem; + + /** size of external memory */ + u32 sizeExMem; + + /** pointer to preallocated shared memory (alternative to fpMalloc) */ + void* pShMem; + + /** size of external memory */ + u32 sizeShMem; + + /** pointer to 0-terminated license key string */ + const char* licenseKey; + + /** maximum image witdh used */ + u32 maxImageWidth; + + /** maximum image height used */ + u32 maxImageHeight; + +} btk_SDKCreateParam; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- functions ---------------------------------------------------------- */ + +/** returns default SDK parameters */ +btk_DECLSPEC +btk_SDKCreateParam btk_SDK_defaultParam( void ); + +/** creates an SDK context using dynamic memory management */ +btk_DECLSPEC +btk_Status btk_SDK_create( const btk_SDKCreateParam* pCreateParamA, + btk_HSDK* hpsdkA ); + +/** closes an SDK context */ +btk_DECLSPEC +btk_Status btk_SDK_close( btk_HSDK hsdkA ); + +/** returns last occurred error and removes it from the error stack */ +btk_DECLSPEC +btk_Error btk_SDK_getError( btk_HSDK hsdkA, + char* msgBufA, + u32 msgBufSizeA ); + +/** returns amount of allocated exclusive memory in bytes */ +btk_DECLSPEC +u32 btk_SDK_exAllocSize( btk_HSDK hsdkA ); + +/** returns amount of allocated shared memory in bytes */ +btk_DECLSPEC +u32 btk_SDK_shAllocSize( btk_HSDK hsdkA ); + +/** returns total amount of allocated memory in bytes */ +btk_DECLSPEC +u32 btk_SDK_allocSize( btk_HSDK hsdkA ); + +#ifdef __cplusplus +} +#endif + +#endif /* btk_SDK_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/SDK_Internal.h b/FaceRecEm/common/src/b_FDSDK/SDK_Internal.h new file mode 100644 index 0000000..b8d7378 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/SDK_Internal.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_SDK_Internal_EM_H +#define btk_SDK_Internal_EM_H + +/** + * SDK object + */ + +/* ---- includes ----------------------------------------------------------- */ + +#include "SDK.h" +#include "b_BasicEm/Context.h" + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** function return status */ +typedef enum +{ + /** sdk handle id */ + btk_HID_SDK, + + /** dcr handle id */ + btk_HID_DCR, + + /** face finder handle id */ + btk_HID_FF + +} btk_HandleId; + + +/** SDK context object */ +struct btk_SDK +{ + /** context (must occur as first element) */ + struct bbs_Context contextE; + + /** handle id */ + btk_HandleId hidE; + + /** reference counter */ + u32 refCtrE; + + /** ptr to malloc function */ + btk_fpMalloc mallocFPtrE; + + /** ptr to free function */ + btk_fpFree freeFPtrE; + + /** error handler function pointer */ + btk_fpError errorFPtrE; + + /* maximum image witdh used */ + u32 maxImageWidthE; + + /* maximum image height used */ + u32 maxImageHeightE; +}; + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- functions ---------------------------------------------------------- */ + +/** tests parameter consistency */ +btk_Status btk_SDK_paramConsistencyTest( struct btk_SDK* hsdkA, + const void* memPtrA, + u32 memSizeA, + const char* fNameA ); + +#endif /* btk_SDK_Internal_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/Types.h b/FaceRecEm/common/src/b_FDSDK/Types.h new file mode 100644 index 0000000..0a3da30 --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/Types.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_TYPES_EM_H +#define btk_TYPES_EM_H + +/** + * This file contains general purpose types. + */ + +/* ---- includes ----------------------------------------------------------- */ + +/* ---- related objects --------------------------------------------------- */ + +/* ---- typedefs ----------------------------------------------------------- */ + +/** elementary data types */ + +/** integer data formats */ +typedef signed short s16; +typedef unsigned short u16; + +#if defined HW_TMS320C6x + + typedef signed int s32; + typedef unsigned int u32; + +#elif defined HW_TMS320C5x + + typedef signed long s32; + typedef unsigned long u32; + +#else + + typedef signed int s32; + typedef unsigned int u32; + +#endif + +/** signed 16.16 fixed point format */ +typedef s32 s16p16; + +/** signed 8.24 fixed point format */ +typedef s32 s8p24; + +/** function return status */ +typedef enum +{ + /** execution finished without error */ + btk_STATUS_OK, + + /** execution could not continue because the object handle was invalid */ + btk_STATUS_INVALID_HANDLE, + + /** execution could not continue because of a preexisting unhandled error condition */ + btk_STATUS_PREEXISTING_ERROR, + + /** execution caused a new error condition */ + btk_STATUS_ERROR + +} btk_Status; + + +/** gallery type */ +typedef enum +{ + /** album gallery */ + btk_GALLERY_ALBUM, + + /** reference gallery */ + btk_GALLERY_REFERENCE + +} btk_GalleryType; + +/** database arrangement type */ +typedef enum +{ + /** database entries are arranged in one coherent memory block without spaces */ + btk_COHERENT, + + /** database entries are arbitrarily distributed in memory and are referenced through pointers */ + btk_DISTRIBUTED + +} btk_DataArrangement; + + +/** error types */ +typedef enum +{ + /** execution finished without error */ + btk_ERR_NO_ERROR, /* no error */ + btk_ERR_INTERNAL, /* internal error */ + btk_ERR_MEMORY, /* failure to allocate memory */ + btk_ERR_VERSION, /* version conflict (software version is older than parameter version) */ + btk_ERR_CORRUPT_DATA /* corrup parameter data or corrupt internal structure */ + +} btk_Error; + +/** the following definitions are used to specify dll handling */ +#if ( defined WIN32 || defined _WIN32_WCE || defined __SYMBIAN32__ ) && !defined btk_NO_DLL + #ifdef btk_EXPORTING + #define btk_DECLSPEC __declspec(dllexport) + #else + #define btk_DECLSPEC __declspec(dllimport) + #endif +#else + #define btk_DECLSPEC +#endif + +/* ---- constants ---------------------------------------------------------- */ + +/* ---- external functions ------------------------------------------------- */ + +#endif /* btk_TYPES_EM_H */ diff --git a/FaceRecEm/common/src/b_FDSDK/fd_emb_sdk.h b/FaceRecEm/common/src/b_FDSDK/fd_emb_sdk.h new file mode 100644 index 0000000..4f6e3bc --- /dev/null +++ b/FaceRecEm/common/src/b_FDSDK/fd_emb_sdk.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef btk_FD_SDK_H +#define btk_FD_SDK_H + +/* header file including all neccessary headers of this library */ + +#include "DCR.h" +#include "FaceFinder.h" +#include "SDK.h" +#include "Types.h" + +#endif /* btk_FD_SDK_H */ diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/MODULE_LICENSE_APACHE2 @@ -0,0 +1,11 @@ + ========================================================================= + == NOTICE file corresponding to the section 4 d of == + == the Apache License, Version 2.0, == + == in this case for the Neven code. == + ========================================================================= + +Neven Code +Copyright (C) 2008 The Android Open Source Project + +This product includes software developed as part of +The Android Open Source Project (http://source.android.com). |