• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011 Apple Inc. All rights reserved.
3  *
4  * @APPLE_APACHE_LICENSE_HEADER_START@
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License") ;
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *	 http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * @APPLE_APACHE_LICENSE_HEADER_END@
19  */
20 
21 /*
22 	File:		dp_dec.c
23 
24 	Contains:	Dynamic Predictor decode routines
25 
26 	Copyright:	(c) 2001-2011 Apple, Inc.
27 */
28 
29 
30 #include <string.h>
31 
32 #include "dplib.h"
33 #include "shift.h"
34 
35 #if __GNUC__
36 #define ALWAYS_INLINE		__attribute__ ((always_inline))
37 #elif defined _MSC_VER
38 #define ALWAYS_INLINE		__forceinline
39 #else
40 #define ALWAYS_INLINE
41 #endif
42 
43 #define LOOP_ALIGN
44 
45 static inline int32_t ALWAYS_INLINE
sign_of_int(int32_t i)46 sign_of_int (int32_t i)
47 {
48 	int32_t negishift ;
49 
50 	negishift = ((uint32_t) - i) >> 31 ;
51 	return negishift | (i >> 31) ;
52 }
53 
54 void
unpc_block(const int32_t * pc1,int32_t * out,int32_t num,int16_t * coefs,int32_t numactive,uint32_t chanbits,uint32_t denshift)55 unpc_block (const int32_t * pc1, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift)
56 {
57 	register int16_t	a0, a1, a2, a3 ;
58 	register int32_t	b0, b1, b2, b3 ;
59 	int32_t					j, k, lim ;
60 	int32_t				sum1, sg, sgn, top, dd ;
61 	int32_t *			pout ;
62 	int32_t				del, del0 ;
63 	uint32_t			chanshift = 32 - chanbits ;
64 	int32_t				denhalf = 1 << (denshift - 1) ;
65 
66 	out [0] = pc1 [0] ;
67 	if (numactive == 0)
68 	{
69 		// just copy if numactive == 0 (but don't bother if in/out pointers the same)
70 		if ((num > 1) && (pc1 != out))
71 			memcpy (&out [1], &pc1 [1], (num - 1) * sizeof (int32_t)) ;
72 		return ;
73 	}
74 	if (numactive == 31)
75 	{
76 		// short-circuit if numactive == 31
77 		int32_t		prev ;
78 
79 		/*	this code is written such that the in/out buffers can be the same
80 			to conserve buffer space on embedded devices like the iPod
81 
82 			(original code)
83 			for (j = 1 ; j < num ; j++)
84 				del = pc1 [j] + out [j-1] ;
85 				out [j] = (del << chanshift) >> chanshift ;
86 		*/
87 		prev = out [0] ;
88 		for (j = 1 ; j < num ; j++)
89 		{
90 			del = pc1 [j] + prev ;
91 			prev = (del << chanshift) >> chanshift ;
92 			out [j] = prev ;
93 		}
94 		return ;
95 	}
96 
97 	for (j = 1 ; j <= numactive ; j++)
98 	{
99 		del = pc1 [j] + out [j-1] ;
100 		out [j] = arith_shift_left (del, chanshift) >> chanshift ;
101 	}
102 
103 	lim = numactive + 1 ;
104 
105 	if (numactive == 4)
106 	{
107 		// optimization for numactive == 4
108 		register int16_t	ia0, ia1, ia2, ia3 ;
109 		register int32_t	ib0, ib1, ib2, ib3 ;
110 
111 		ia0 = coefs [0] ;
112 		ia1 = coefs [1] ;
113 		ia2 = coefs [2] ;
114 		ia3 = coefs [3] ;
115 
116 		for (j = lim ; j < num ; j++)
117 		{
118 			LOOP_ALIGN
119 
120 			top = out [j - lim] ;
121 			pout = out + j - 1 ;
122 
123 			ib0 = top - pout [0] ;
124 			ib1 = top - pout [-1] ;
125 			ib2 = top - pout [-2] ;
126 			ib3 = top - pout [-3] ;
127 
128 			sum1 = (denhalf - ia0 * ib0 - ia1 * ib1 - ia2 * ib2 - ia3 * ib3) >> denshift ;
129 
130 			del = pc1 [j] ;
131 			del0 = del ;
132 			sg = sign_of_int (del) ;
133 			del += top + sum1 ;
134 
135 			out [j] = arith_shift_left (del, chanshift) >> chanshift ;
136 
137 			if (sg > 0)
138 			{
139 				sgn = sign_of_int (ib3) ;
140 				ia3 -= sgn ;
141 				del0 -= (4 - 3) * ((sgn * ib3) >> denshift) ;
142 				if (del0 <= 0)
143 					continue ;
144 
145 				sgn = sign_of_int (ib2) ;
146 				ia2 -= sgn ;
147 				del0 -= (4 - 2) * ((sgn * ib2) >> denshift) ;
148 				if (del0 <= 0)
149 					continue ;
150 
151 				sgn = sign_of_int (ib1) ;
152 				ia1 -= sgn ;
153 				del0 -= (4 - 1) * ((sgn * ib1) >> denshift) ;
154 				if (del0 <= 0)
155 					continue ;
156 
157 				ia0 -= sign_of_int (ib0) ;
158 			}
159 			else if (sg < 0)
160 			{
161 				// note: to avoid unnecessary negations, we flip the value of "sgn"
162 				sgn = -sign_of_int (ib3) ;
163 				ia3 -= sgn ;
164 				del0 -= (4 - 3) * ((sgn * ib3) >> denshift) ;
165 				if (del0 >= 0)
166 					continue ;
167 
168 				sgn = -sign_of_int (ib2) ;
169 				ia2 -= sgn ;
170 				del0 -= (4 - 2) * ((sgn * ib2) >> denshift) ;
171 				if (del0 >= 0)
172 					continue ;
173 
174 				sgn = -sign_of_int (ib1) ;
175 				ia1 -= sgn ;
176 				del0 -= (4 - 1) * ((sgn * ib1) >> denshift) ;
177 				if (del0 >= 0)
178 					continue ;
179 
180 				ia0 += sign_of_int (ib0) ;
181 			}
182 		}
183 
184 		coefs [0] = ia0 ;
185 		coefs [1] = ia1 ;
186 		coefs [2] = ia2 ;
187 		coefs [3] = ia3 ;
188 	}
189 	else if (numactive == 8)
190 	{
191 		register int16_t	a4, a5, a6, a7 ;
192 		register int32_t	b4, b5, b6, b7 ;
193 
194 		// optimization for numactive == 8
195 		a0 = coefs [0] ;
196 		a1 = coefs [1] ;
197 		a2 = coefs [2] ;
198 		a3 = coefs [3] ;
199 		a4 = coefs [4] ;
200 		a5 = coefs [5] ;
201 		a6 = coefs [6] ;
202 		a7 = coefs [7] ;
203 
204 		for (j = lim ; j < num ; j++)
205 		{
206 			LOOP_ALIGN
207 
208 			top = out [j - lim] ;
209 			pout = out + j - 1 ;
210 
211 			b0 = top - (*pout--) ;
212 			b1 = top - (*pout--) ;
213 			b2 = top - (*pout--) ;
214 			b3 = top - (*pout--) ;
215 			b4 = top - (*pout--) ;
216 			b5 = top - (*pout--) ;
217 			b6 = top - (*pout--) ;
218 			b7 = top - (*pout) ;
219 			pout += 8 ;
220 
221 			sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
222 					- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift ;
223 
224 			del = pc1 [j] ;
225 			del0 = del ;
226 			sg = sign_of_int (del) ;
227 			del += top + sum1 ;
228 
229 			out [j] = arith_shift_left (del, chanshift) >> chanshift ;
230 
231 			if (sg > 0)
232 			{
233 				sgn = sign_of_int (b7) ;
234 				a7 -= sgn ;
235 				del0 -= 1 * ((sgn * b7) >> denshift) ;
236 				if (del0 <= 0)
237 					continue ;
238 
239 				sgn = sign_of_int (b6) ;
240 				a6 -= sgn ;
241 				del0 -= 2 * ((sgn * b6) >> denshift) ;
242 				if (del0 <= 0)
243 					continue ;
244 
245 				sgn = sign_of_int (b5) ;
246 				a5 -= sgn ;
247 				del0 -= 3 * ((sgn * b5) >> denshift) ;
248 				if (del0 <= 0)
249 					continue ;
250 
251 				sgn = sign_of_int (b4) ;
252 				a4 -= sgn ;
253 				del0 -= 4 * ((sgn * b4) >> denshift) ;
254 				if (del0 <= 0)
255 					continue ;
256 
257 				sgn = sign_of_int (b3) ;
258 				a3 -= sgn ;
259 				del0 -= 5 * ((sgn * b3) >> denshift) ;
260 				if (del0 <= 0)
261 					continue ;
262 
263 				sgn = sign_of_int (b2) ;
264 				a2 -= sgn ;
265 				del0 -= 6 * ((sgn * b2) >> denshift) ;
266 				if (del0 <= 0)
267 					continue ;
268 
269 				sgn = sign_of_int (b1) ;
270 				a1 -= sgn ;
271 				del0 -= 7 * ((sgn * b1) >> denshift) ;
272 				if (del0 <= 0)
273 					continue ;
274 
275 				a0 -= sign_of_int (b0) ;
276 			}
277 			else if (sg < 0)
278 			{
279 				// note: to avoid unnecessary negations, we flip the value of "sgn"
280 				sgn = -sign_of_int (b7) ;
281 				a7 -= sgn ;
282 				del0 -= 1 * ((sgn * b7) >> denshift) ;
283 				if (del0 >= 0)
284 					continue ;
285 
286 				sgn = -sign_of_int (b6) ;
287 				a6 -= sgn ;
288 				del0 -= 2 * ((sgn * b6) >> denshift) ;
289 				if (del0 >= 0)
290 					continue ;
291 
292 				sgn = -sign_of_int (b5) ;
293 				a5 -= sgn ;
294 				del0 -= 3 * ((sgn * b5) >> denshift) ;
295 				if (del0 >= 0)
296 					continue ;
297 
298 				sgn = -sign_of_int (b4) ;
299 				a4 -= sgn ;
300 				del0 -= 4 * ((sgn * b4) >> denshift) ;
301 				if (del0 >= 0)
302 					continue ;
303 
304 				sgn = -sign_of_int (b3) ;
305 				a3 -= sgn ;
306 				del0 -= 5 * ((sgn * b3) >> denshift) ;
307 				if (del0 >= 0)
308 					continue ;
309 
310 				sgn = -sign_of_int (b2) ;
311 				a2 -= sgn ;
312 				del0 -= 6 * ((sgn * b2) >> denshift) ;
313 				if (del0 >= 0)
314 					continue ;
315 
316 				sgn = -sign_of_int (b1) ;
317 				a1 -= sgn ;
318 				del0 -= 7 * ((sgn * b1) >> denshift) ;
319 				if (del0 >= 0)
320 					continue ;
321 
322 				a0 += sign_of_int (b0) ;
323 			}
324 		}
325 
326 		coefs [0] = a0 ;
327 		coefs [1] = a1 ;
328 		coefs [2] = a2 ;
329 		coefs [3] = a3 ;
330 		coefs [4] = a4 ;
331 		coefs [5] = a5 ;
332 		coefs [6] = a6 ;
333 		coefs [7] = a7 ;
334 	}
335 	else
336 	{
337 		// general case
338 		for (j = lim ; j < num ; j++)
339 		{
340 			LOOP_ALIGN
341 
342 			sum1 = 0 ;
343 			pout = out + j - 1 ;
344 			top = out [j-lim] ;
345 
346 			for (k = 0 ; k < numactive ; k++)
347 				sum1 += coefs [k] * (pout [-k] - top) ;
348 
349 			del = pc1 [j] ;
350 			del0 = del ;
351 			sg = sign_of_int (del) ;
352 			del += top + ((sum1 + denhalf) >> denshift) ;
353 			out [j] = (del << chanshift) >> chanshift ;
354 
355 			if (sg > 0)
356 			{
357 				for (k = (numactive - 1) ; k >= 0 ; k--)
358 				{
359 					dd = top - pout [-k] ;
360 					sgn = sign_of_int (dd) ;
361 					coefs [k] -= sgn ;
362 					del0 -= (numactive - k) * ((sgn * dd) >> denshift) ;
363 					if (del0 <= 0)
364 						break ;
365 				}
366 			}
367 			else if (sg < 0)
368 			{
369 				for (k = (numactive - 1) ; k >= 0 ; k--)
370 				{
371 					dd = top - pout [-k] ;
372 					sgn = sign_of_int (dd) ;
373 					coefs [k] += sgn ;
374 					del0 -= (numactive - k) * ((-sgn * dd) >> denshift) ;
375 					if (del0 >= 0)
376 						break ;
377 				}
378 			}
379 		}
380 	}
381 }
382