Initial Contribution
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
new file mode 100644
index 0000000..00f96a6
--- /dev/null
+++ b/Embedded/common/data/APIEm/Modules/RFFprec_501.bmd
Binary files differ
diff --git a/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd b/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd
new file mode 100644
index 0000000..e7299a5
--- /dev/null
+++ b/Embedded/common/data/APIEm/Modules/RFFspeed_501.bmd
Binary files differ
diff --git a/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd b/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd
new file mode 100644
index 0000000..2187396
--- /dev/null
+++ b/Embedded/common/data/APIEm/Modules/RFFstd_501.bmd
Binary files differ
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, &centerL );
+	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, &centerL );
+	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( &quotientL, &quotientBbpL, 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( &quotientL, &quotientBbpL, 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, &centerInL );
+
+	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..aacf34c
--- /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 <graphics/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
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..6a55eac
--- /dev/null
+++ b/NOTICE
@@ -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).