1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* ---- includes ----------------------------------------------------------- */
18
19#include "b_APIEm/Functions.h"
20#include "b_BasicEm/Memory.h"
21
22
23/* ---- related objects  --------------------------------------------------- */
24
25/* ---- typedefs ----------------------------------------------------------- */
26
27/* ---- constants ---------------------------------------------------------- */
28
29/* ------------------------------------------------------------------------- */
30
31/* ========================================================================= */
32/*                                                                           */
33/* ---- \ghd{ external functions } ----------------------------------------- */
34/*                                                                           */
35/* ========================================================================= */
36
37/* ------------------------------------------------------------------------- */
38
39void bpi_normalizeSimilarities( struct bbs_Context* cpA,
40							    const int32* rawSimArrA,
41							    const int32* rawIdArrA,
42								uint32 rawSizeA,
43								const int32* refSimArrA,
44								const int32* refIdArrA,
45								uint32 refSizeA,
46								enum bpi_SimType simTypeA,
47								int32* outSimArrA )
48{
49	/* 8.24 */
50	int32 refSimL = 0;
51	uint32 iL, jL, kL;
52	int32* outPtrL = outSimArrA;
53	const int32* rawPtrL = rawSimArrA;
54
55	switch( simTypeA )
56	{
57		case bpi_RAW_SIM:
58		{
59			/* nothing to do */
60		}
61		break;
62
63		case bpi_SUB_MEAN:
64		{
65			int32 shiftL = 0;
66			int32 roundL = 0;
67			refSimL = 0;
68			for( iL = 0; iL < refSizeA; iL++ )
69			{
70				refSimL += ( refSimArrA[ iL ] + roundL ) >> shiftL;
71				if( refSimL > 0x40000000 )
72				{
73					refSimL = ( refSimL + 1 ) >> 1;
74					shiftL++;
75					roundL = ( int32 )1 << ( shiftL - 1 );
76				}
77			}
78			refSimL = ( refSimL / refSizeA ) << shiftL;
79		}
80		break;
81
82		case bpi_SUB_MAX_2:
83		{
84			int32 maxL = 0;
85			uint32 maxIndexL = 0;
86			int32 idL = 0;
87
88			/* find raw maximum */
89			for( iL = 0; iL < rawSizeA; iL++ )
90			{
91				if( maxL < rawSimArrA[ iL ] )
92				{
93					maxL = refSimArrA[ iL ];
94					maxIndexL = iL;
95				}
96			}
97
98			/* consider id of maximum equal to probe id */
99			idL = rawIdArrA[ maxIndexL ];
100
101			/* find maximum similarity in ref array of different id */
102			for( iL = 0; iL < refSizeA; iL++ )
103			{
104				if( refIdArrA[ iL ] != idL )
105				{
106					refSimL = ( refSimL > refSimArrA[ iL ] ) ? refSimL : refSimArrA[ iL ];
107				}
108			}
109		}
110		break;
111
112		case bpi_SUB_16_MAX_2:
113		{
114			int32 maxL = 0;
115			uint32 maxIndexL = 0;
116			int32 idL = 0;
117
118			int32 maxSimArrL[ 16 ];
119			bbs_memset32( maxSimArrL, ( uint32 )-1, bbs_SIZEOF32( maxSimArrL ) );
120
121			/* find raw maximum */
122			for( iL = 0; iL < rawSizeA; iL++ )
123			{
124				if( maxL < rawSimArrA[ iL ] )
125				{
126					maxL = rawSimArrA[ iL ];
127					maxIndexL = iL;
128				}
129			}
130
131			/* consider id of maximum equal to probe id */
132			idL = rawIdArrA[ maxIndexL ];
133
134			/* find 16 maximum similarities of different id in ref array */
135			for( iL = 0; iL < refSizeA; iL++ )
136			{
137				if( refIdArrA[ iL ] != idL )
138				{
139					int32 simL = refSimArrA[ iL ];
140					for( jL = 0; jL < 16; jL++ )
141					{
142						if( simL > maxSimArrL[ jL ] ) break;
143					}
144					for( kL = 15; kL > jL; kL-- )
145					{
146						maxSimArrL[ kL ] = maxSimArrL[ kL - 1 ];
147					}
148					if( jL < 16 ) maxSimArrL[ jL ] = simL;
149				}
150			}
151
152			refSimL = 0;
153			for( jL = 0; jL < 16; jL++ )
154			{
155				if( maxSimArrL[ jL ] == -1 ) break;
156				refSimL += maxSimArrL[ jL ];
157			}
158
159			if( jL > 0 )
160			{
161				refSimL /= jL;
162			}
163		}
164		break;
165
166		default:
167		{
168			bbs_ERROR1( "void bpi_Identifier_normalizeSimilarities(): simTypeA '%i' is handled", simTypeA );
169			return;
170		}
171	}
172
173	/* refSimL -= 1.0 */
174	refSimL -= ( (uint32)1 << 24 );
175
176	for( iL = rawSizeA; iL > 0; iL-- )
177	{
178		*outPtrL++ = ( *rawPtrL++ - refSimL + 1 ) >> 1;
179	}
180
181}
182
183/* ------------------------------------------------------------------------- */
184
185int32 bpi_normalizedSimilarity( struct bbs_Context* cpA,
186							    int32 rawSimA,
187							    int32 rawIdA,
188								const int32* refSimArrA,
189								const int32* refIdArrA,
190								uint32 refSizeA,
191								enum bpi_SimType simTypeA )
192{
193	/* 8.24 */
194	int32 refSimL = 0;
195	uint32 iL, jL, kL;
196
197	switch( simTypeA )
198	{
199		case bpi_RAW_SIM:
200		{
201			/* nothing to do */
202			return rawSimA; /* return without adjustment of value range */
203		}
204
205		case bpi_SUB_MEAN:
206		{
207			int32 shiftL = 0;
208			int32 roundL = 0;
209			refSimL = 0;
210			for( iL = 0; iL < refSizeA; iL++ )
211			{
212				refSimL += ( refSimArrA[ iL ] + roundL ) >> shiftL;
213				if( refSimL > 0x40000000 )
214				{
215					refSimL = ( refSimL + 1 ) >> 1;
216					shiftL++;
217					roundL = ( int32 )1 << ( shiftL - 1 );
218				}
219			}
220			refSimL = ( refSimL / refSizeA ) << shiftL;
221		}
222		break;
223
224		case bpi_SUB_MAX_2:
225		{
226			/* find maximum similarity in ref array of different rawIdA */
227			for( iL = 0; iL < refSizeA; iL++ )
228			{
229				if( refIdArrA[ iL ] != rawIdA )
230				{
231					refSimL = ( refSimL > refSimArrA[ iL ] ) ? refSimL : refSimArrA[ iL ];
232				}
233			}
234		}
235		break;
236
237		case bpi_SUB_16_MAX_2:
238		{
239			int32 maxSimArrL[ 16 ];
240			int32 idL = rawIdA;
241			bbs_memset32( maxSimArrL, ( uint32 )-1, bbs_SIZEOF32( maxSimArrL ) );
242
243			/* find 16 maximum similarities of different id in ref array */
244			for( iL = 0; iL < refSizeA; iL++ )
245			{
246				if( refIdArrA[ iL ] != idL )
247				{
248					int32 simL = refSimArrA[ iL ];
249					for( jL = 0; jL < 16; jL++ )
250					{
251						if( simL > maxSimArrL[ jL ] ) break;
252					}
253					for( kL = 15; kL > jL; kL-- )
254					{
255						maxSimArrL[ kL ] = maxSimArrL[ kL - 1 ];
256					}
257					if( jL < 16 ) maxSimArrL[ jL ] = simL;
258				}
259			}
260
261			refSimL = 0;
262			for( jL = 0; jL < 16; jL++ )
263			{
264				if( maxSimArrL[ jL ] == -1 ) break;
265				refSimL += maxSimArrL[ jL ];
266			}
267
268			if( jL > 0 )
269			{
270				refSimL /= jL;
271			}
272		}
273		break;
274
275		default:
276		{
277			bbs_ERROR1( "void bpi_Identifier_normalizeSimilarities(): simTypeA '%i' is handled", simTypeA );
278		}
279		break;
280	}
281
282	/* refSimL -= 1.0 */
283	refSimL -= ( (uint32)1 << 24 );
284	return ( rawSimA - refSimL + 1 ) >> 1;
285}
286
287/* ------------------------------------------------------------------------- */
288
289uint32 bpi_memWriteCsa16( uint16* memPtrA, uint32 memSizeA, uint16 chkSumA )
290{
291	uint16* memPtrL = memPtrA - memSizeA + 1;
292	uint32 iL;
293	uint16 sumL = 0;
294	uint16 csaL = 0;
295
296	bbs_memWrite16( &csaL, memPtrA );
297	for( iL = 0; iL < memSizeA; iL++ )
298	{
299		uint16 valL = 0;
300		memPtrL += bbs_memRead16( &valL, memPtrL );
301		sumL += valL;
302	}
303	csaL = chkSumA - sumL;
304
305	return bbs_memWrite16( &csaL, memPtrA );
306}
307
308/* ------------------------------------------------------------------------- */
309
310uint32 bpi_memReadCsa16( const uint16* memPtrA )
311{
312	return bbs_SIZEOF16( uint16 );
313}
314
315/* ------------------------------------------------------------------------- */
316
317