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