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