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 
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)39 void 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 
bpi_normalizedSimilarity(struct bbs_Context * cpA,int32 rawSimA,int32 rawIdA,const int32 * refSimArrA,const int32 * refIdArrA,uint32 refSizeA,enum bpi_SimType simTypeA)185 int32 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 
bpi_memWriteCsa16(uint16 * memPtrA,uint32 memSizeA,uint16 chkSumA)289 uint32 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 
bpi_memReadCsa16(const uint16 * memPtrA)310 uint32 bpi_memReadCsa16( const uint16* memPtrA )
311 {
312 	return bbs_SIZEOF16( uint16 );
313 }
314 
315 /* ------------------------------------------------------------------------- */
316 
317