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 45static inline int32_t ALWAYS_INLINE 46sign_of_int (int32_t i) 47{ 48 int32_t negishift ; 49 50 negishift = ((uint32_t) - i) >> 31 ; 51 return negishift | (i >> 31) ; 52} 53 54void 55unpc_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