• 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 #else
38 #define ALWAYS_INLINE
39 #endif
40 
41 #define LOOP_ALIGN
42 
43 static inline int32_t ALWAYS_INLINE
sign_of_int(int32_t i)44 sign_of_int (int32_t i)
45 {
46 	int32_t negishift ;
47 
48 	negishift = ((uint32_t) - i) >> 31 ;
49 	return negishift | (i >> 31) ;
50 }
51 
52 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)53 unpc_block (const int32_t * pc1, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift)
54 {
55 	register int16_t	a0, a1, a2, a3 ;
56 	register int32_t	b0, b1, b2, b3 ;
57 	int32_t					j, k, lim ;
58 	int32_t				sum1, sg, sgn, top, dd ;
59 	int32_t *			pout ;
60 	int32_t				del, del0 ;
61 	uint32_t			chanshift = 32 - chanbits ;
62 	int32_t				denhalf = 1 << (denshift - 1) ;
63 
64 	out [0] = pc1 [0] ;
65 	if (numactive == 0)
66 	{
67 		// just copy if numactive == 0 (but don't bother if in/out pointers the same)
68 		if ((num > 1) && (pc1 != out))
69 			memcpy (&out [1], &pc1 [1], (num - 1) * sizeof (int32_t)) ;
70 		return ;
71 	}
72 	if (numactive == 31)
73 	{
74 		// short-circuit if numactive == 31
75 		int32_t		prev ;
76 
77 		/*	this code is written such that the in/out buffers can be the same
78 			to conserve buffer space on embedded devices like the iPod
79 
80 			(original code)
81 			for (j = 1 ; j < num ; j++)
82 				del = pc1 [j] + out [j-1] ;
83 				out [j] = (del << chanshift) >> chanshift ;
84 		*/
85 		prev = out [0] ;
86 		for (j = 1 ; j < num ; j++)
87 		{
88 			del = pc1 [j] + prev ;
89 			prev = (del << chanshift) >> chanshift ;
90 			out [j] = prev ;
91 		}
92 		return ;
93 	}
94 
95 	for (j = 1 ; j <= numactive ; j++)
96 	{
97 		del = pc1 [j] + out [j-1] ;
98 		out [j] = arith_shift_left (del, chanshift) >> chanshift ;
99 	}
100 
101 	lim = numactive + 1 ;
102 
103 	if (numactive == 4)
104 	{
105 		// optimization for numactive == 4
106 		register int16_t	ia0, ia1, ia2, ia3 ;
107 		register int32_t	ib0, ib1, ib2, ib3 ;
108 
109 		ia0 = coefs [0] ;
110 		ia1 = coefs [1] ;
111 		ia2 = coefs [2] ;
112 		ia3 = coefs [3] ;
113 
114 		for (j = lim ; j < num ; j++)
115 		{
116 			LOOP_ALIGN
117 
118 			top = out [j - lim] ;
119 			pout = out + j - 1 ;
120 
121 			ib0 = top - pout [0] ;
122 			ib1 = top - pout [-1] ;
123 			ib2 = top - pout [-2] ;
124 			ib3 = top - pout [-3] ;
125 
126 			sum1 = (denhalf - ia0 * ib0 - ia1 * ib1 - ia2 * ib2 - ia3 * ib3) >> denshift ;
127 
128 			del = pc1 [j] ;
129 			del0 = del ;
130 			sg = sign_of_int (del) ;
131 			del += top + sum1 ;
132 
133 			out [j] = arith_shift_left (del, chanshift) >> chanshift ;
134 
135 			if (sg > 0)
136 			{
137 				sgn = sign_of_int (ib3) ;
138 				ia3 -= sgn ;
139 				del0 -= (4 - 3) * ((sgn * ib3) >> denshift) ;
140 				if (del0 <= 0)
141 					continue ;
142 
143 				sgn = sign_of_int (ib2) ;
144 				ia2 -= sgn ;
145 				del0 -= (4 - 2) * ((sgn * ib2) >> denshift) ;
146 				if (del0 <= 0)
147 					continue ;
148 
149 				sgn = sign_of_int (ib1) ;
150 				ia1 -= sgn ;
151 				del0 -= (4 - 1) * ((sgn * ib1) >> denshift) ;
152 				if (del0 <= 0)
153 					continue ;
154 
155 				ia0 -= sign_of_int (ib0) ;
156 			}
157 			else if (sg < 0)
158 			{
159 				// note: to avoid unnecessary negations, we flip the value of "sgn"
160 				sgn = -sign_of_int (ib3) ;
161 				ia3 -= sgn ;
162 				del0 -= (4 - 3) * ((sgn * ib3) >> denshift) ;
163 				if (del0 >= 0)
164 					continue ;
165 
166 				sgn = -sign_of_int (ib2) ;
167 				ia2 -= sgn ;
168 				del0 -= (4 - 2) * ((sgn * ib2) >> denshift) ;
169 				if (del0 >= 0)
170 					continue ;
171 
172 				sgn = -sign_of_int (ib1) ;
173 				ia1 -= sgn ;
174 				del0 -= (4 - 1) * ((sgn * ib1) >> denshift) ;
175 				if (del0 >= 0)
176 					continue ;
177 
178 				ia0 += sign_of_int (ib0) ;
179 			}
180 		}
181 
182 		coefs [0] = ia0 ;
183 		coefs [1] = ia1 ;
184 		coefs [2] = ia2 ;
185 		coefs [3] = ia3 ;
186 	}
187 	else if (numactive == 8)
188 	{
189 		register int16_t	a4, a5, a6, a7 ;
190 		register int32_t	b4, b5, b6, b7 ;
191 
192 		// optimization for numactive == 8
193 		a0 = coefs [0] ;
194 		a1 = coefs [1] ;
195 		a2 = coefs [2] ;
196 		a3 = coefs [3] ;
197 		a4 = coefs [4] ;
198 		a5 = coefs [5] ;
199 		a6 = coefs [6] ;
200 		a7 = coefs [7] ;
201 
202 		for (j = lim ; j < num ; j++)
203 		{
204 			LOOP_ALIGN
205 
206 			top = out [j - lim] ;
207 			pout = out + j - 1 ;
208 
209 			b0 = top - (*pout--) ;
210 			b1 = top - (*pout--) ;
211 			b2 = top - (*pout--) ;
212 			b3 = top - (*pout--) ;
213 			b4 = top - (*pout--) ;
214 			b5 = top - (*pout--) ;
215 			b6 = top - (*pout--) ;
216 			b7 = top - (*pout) ;
217 			pout += 8 ;
218 
219 			sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
220 					- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift ;
221 
222 			del = pc1 [j] ;
223 			del0 = del ;
224 			sg = sign_of_int (del) ;
225 			del += top + sum1 ;
226 
227 			out [j] = arith_shift_left (del, chanshift) >> chanshift ;
228 
229 			if (sg > 0)
230 			{
231 				sgn = sign_of_int (b7) ;
232 				a7 -= sgn ;
233 				del0 -= 1 * ((sgn * b7) >> denshift) ;
234 				if (del0 <= 0)
235 					continue ;
236 
237 				sgn = sign_of_int (b6) ;
238 				a6 -= sgn ;
239 				del0 -= 2 * ((sgn * b6) >> denshift) ;
240 				if (del0 <= 0)
241 					continue ;
242 
243 				sgn = sign_of_int (b5) ;
244 				a5 -= sgn ;
245 				del0 -= 3 * ((sgn * b5) >> denshift) ;
246 				if (del0 <= 0)
247 					continue ;
248 
249 				sgn = sign_of_int (b4) ;
250 				a4 -= sgn ;
251 				del0 -= 4 * ((sgn * b4) >> denshift) ;
252 				if (del0 <= 0)
253 					continue ;
254 
255 				sgn = sign_of_int (b3) ;
256 				a3 -= sgn ;
257 				del0 -= 5 * ((sgn * b3) >> denshift) ;
258 				if (del0 <= 0)
259 					continue ;
260 
261 				sgn = sign_of_int (b2) ;
262 				a2 -= sgn ;
263 				del0 -= 6 * ((sgn * b2) >> denshift) ;
264 				if (del0 <= 0)
265 					continue ;
266 
267 				sgn = sign_of_int (b1) ;
268 				a1 -= sgn ;
269 				del0 -= 7 * ((sgn * b1) >> denshift) ;
270 				if (del0 <= 0)
271 					continue ;
272 
273 				a0 -= sign_of_int (b0) ;
274 			}
275 			else if (sg < 0)
276 			{
277 				// note: to avoid unnecessary negations, we flip the value of "sgn"
278 				sgn = -sign_of_int (b7) ;
279 				a7 -= sgn ;
280 				del0 -= 1 * ((sgn * b7) >> denshift) ;
281 				if (del0 >= 0)
282 					continue ;
283 
284 				sgn = -sign_of_int (b6) ;
285 				a6 -= sgn ;
286 				del0 -= 2 * ((sgn * b6) >> denshift) ;
287 				if (del0 >= 0)
288 					continue ;
289 
290 				sgn = -sign_of_int (b5) ;
291 				a5 -= sgn ;
292 				del0 -= 3 * ((sgn * b5) >> denshift) ;
293 				if (del0 >= 0)
294 					continue ;
295 
296 				sgn = -sign_of_int (b4) ;
297 				a4 -= sgn ;
298 				del0 -= 4 * ((sgn * b4) >> denshift) ;
299 				if (del0 >= 0)
300 					continue ;
301 
302 				sgn = -sign_of_int (b3) ;
303 				a3 -= sgn ;
304 				del0 -= 5 * ((sgn * b3) >> denshift) ;
305 				if (del0 >= 0)
306 					continue ;
307 
308 				sgn = -sign_of_int (b2) ;
309 				a2 -= sgn ;
310 				del0 -= 6 * ((sgn * b2) >> denshift) ;
311 				if (del0 >= 0)
312 					continue ;
313 
314 				sgn = -sign_of_int (b1) ;
315 				a1 -= sgn ;
316 				del0 -= 7 * ((sgn * b1) >> denshift) ;
317 				if (del0 >= 0)
318 					continue ;
319 
320 				a0 += sign_of_int (b0) ;
321 			}
322 		}
323 
324 		coefs [0] = a0 ;
325 		coefs [1] = a1 ;
326 		coefs [2] = a2 ;
327 		coefs [3] = a3 ;
328 		coefs [4] = a4 ;
329 		coefs [5] = a5 ;
330 		coefs [6] = a6 ;
331 		coefs [7] = a7 ;
332 	}
333 	else
334 	{
335 		// general case
336 		for (j = lim ; j < num ; j++)
337 		{
338 			LOOP_ALIGN
339 
340 			sum1 = 0 ;
341 			pout = out + j - 1 ;
342 			top = out [j-lim] ;
343 
344 			for (k = 0 ; k < numactive ; k++)
345 				sum1 += coefs [k] * (pout [-k] - top) ;
346 
347 			del = pc1 [j] ;
348 			del0 = del ;
349 			sg = sign_of_int (del) ;
350 			del += top + ((sum1 + denhalf) >> denshift) ;
351 			out [j] = (del << chanshift) >> chanshift ;
352 
353 			if (sg > 0)
354 			{
355 				for (k = (numactive - 1) ; k >= 0 ; k--)
356 				{
357 					dd = top - pout [-k] ;
358 					sgn = sign_of_int (dd) ;
359 					coefs [k] -= sgn ;
360 					del0 -= (numactive - k) * ((sgn * dd) >> denshift) ;
361 					if (del0 <= 0)
362 						break ;
363 				}
364 			}
365 			else if (sg < 0)
366 			{
367 				for (k = (numactive - 1) ; k >= 0 ; k--)
368 				{
369 					dd = top - pout [-k] ;
370 					sgn = sign_of_int (dd) ;
371 					coefs [k] += sgn ;
372 					del0 -= (numactive - k) * ((-sgn * dd) >> denshift) ;
373 					if (del0 >= 0)
374 						break ;
375 				}
376 			}
377 		}
378 	}
379 }
380