dp_enc.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  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. File: dp_enc.c
  22. Contains: Dynamic Predictor encode routines
  23. Copyright: (c) 2001-2011 Apple, Inc.
  24. */
  25. #include "dplib.h"
  26. #include <string.h>
  27. #if __GNUC__
  28. #define ALWAYS_INLINE __attribute__((always_inline))
  29. #else
  30. #define ALWAYS_INLINE
  31. #endif
  32. #if TARGET_CPU_PPC && (__MWERKS__ >= 0x3200)
  33. // align loops to a 16 byte boundary to make the G5 happy
  34. #pragma function_align 16
  35. #define LOOP_ALIGN asm { align 16 }
  36. #else
  37. #define LOOP_ALIGN
  38. #endif
  39. void init_coefs( int16_t * coefs, uint32_t denshift, int32_t numPairs )
  40. {
  41. int32_t k;
  42. int32_t den = 1 << denshift;
  43. coefs[0] = (AINIT * den) >> 4;
  44. coefs[1] = (BINIT * den) >> 4;
  45. coefs[2] = (CINIT * den) >> 4;
  46. for ( k = 3; k < numPairs; k++ )
  47. coefs[k] = 0;
  48. }
  49. void copy_coefs( int16_t * srcCoefs, int16_t * dstCoefs, int32_t numPairs )
  50. {
  51. int32_t k;
  52. for ( k = 0; k < numPairs; k++ )
  53. dstCoefs[k] = srcCoefs[k];
  54. }
  55. static inline int32_t ALWAYS_INLINE sign_of_int( int32_t i )
  56. {
  57. int32_t negishift;
  58. negishift = ((uint32_t)-i) >> 31;
  59. return negishift | (i >> 31);
  60. }
  61. void pc_block( int32_t * in, int32_t * pc1, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift )
  62. {
  63. register int16_t a0, a1, a2, a3;
  64. register int32_t b0, b1, b2, b3;
  65. int32_t j, k, lim;
  66. int32_t * pin;
  67. int32_t sum1, dd;
  68. int32_t sg, sgn;
  69. int32_t top;
  70. int32_t del, del0;
  71. uint32_t chanshift = 32 - chanbits;
  72. int32_t denhalf = 1 << (denshift - 1);
  73. pc1[0] = in[0];
  74. if ( numactive == 0 )
  75. {
  76. // just copy if numactive == 0 (but don't bother if in/out pointers the same)
  77. if ( (num > 1) && (in != pc1) )
  78. memcpy( &pc1[1], &in[1], (num - 1) * sizeof(int32_t) );
  79. return;
  80. }
  81. if ( numactive == 31 )
  82. {
  83. // short-circuit if numactive == 31
  84. for( j = 1; j < num; j++ )
  85. {
  86. del = in[j] - in[j-1];
  87. pc1[j] = (del << chanshift) >> chanshift;
  88. }
  89. return;
  90. }
  91. for ( j = 1; j <= numactive; j++ )
  92. {
  93. del = in[j] - in[j-1];
  94. pc1[j] = (del << chanshift) >> chanshift;
  95. }
  96. lim = numactive + 1;
  97. if ( numactive == 4 )
  98. {
  99. // optimization for numactive == 4
  100. a0 = coefs[0];
  101. a1 = coefs[1];
  102. a2 = coefs[2];
  103. a3 = coefs[3];
  104. for ( j = lim; j < num; j++ )
  105. {
  106. LOOP_ALIGN
  107. top = in[j - lim];
  108. pin = in + j - 1;
  109. b0 = top - pin[0];
  110. b1 = top - pin[-1];
  111. b2 = top - pin[-2];
  112. b3 = top - pin[-3];
  113. sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3) >> denshift;
  114. del = in[j] - top - sum1;
  115. del = (del << chanshift) >> chanshift;
  116. pc1[j] = del;
  117. del0 = del;
  118. sg = sign_of_int(del);
  119. if ( sg > 0 )
  120. {
  121. sgn = sign_of_int( b3 );
  122. a3 -= sgn;
  123. del0 -= (4 - 3) * ((sgn * b3) >> denshift);
  124. if ( del0 <= 0 )
  125. continue;
  126. sgn = sign_of_int( b2 );
  127. a2 -= sgn;
  128. del0 -= (4 - 2) * ((sgn * b2) >> denshift);
  129. if ( del0 <= 0 )
  130. continue;
  131. sgn = sign_of_int( b1 );
  132. a1 -= sgn;
  133. del0 -= (4 - 1) * ((sgn * b1) >> denshift);
  134. if ( del0 <= 0 )
  135. continue;
  136. a0 -= sign_of_int( b0 );
  137. }
  138. else if ( sg < 0 )
  139. {
  140. // note: to avoid unnecessary negations, we flip the value of "sgn"
  141. sgn = -sign_of_int( b3 );
  142. a3 -= sgn;
  143. del0 -= (4 - 3) * ((sgn * b3) >> denshift);
  144. if ( del0 >= 0 )
  145. continue;
  146. sgn = -sign_of_int( b2 );
  147. a2 -= sgn;
  148. del0 -= (4 - 2) * ((sgn * b2) >> denshift);
  149. if ( del0 >= 0 )
  150. continue;
  151. sgn = -sign_of_int( b1 );
  152. a1 -= sgn;
  153. del0 -= (4 - 1) * ((sgn * b1) >> denshift);
  154. if ( del0 >= 0 )
  155. continue;
  156. a0 += sign_of_int( b0 );
  157. }
  158. }
  159. coefs[0] = a0;
  160. coefs[1] = a1;
  161. coefs[2] = a2;
  162. coefs[3] = a3;
  163. }
  164. else if ( numactive == 8 )
  165. {
  166. // optimization for numactive == 8
  167. register int16_t a4, a5, a6, a7;
  168. register int32_t b4, b5, b6, b7;
  169. a0 = coefs[0];
  170. a1 = coefs[1];
  171. a2 = coefs[2];
  172. a3 = coefs[3];
  173. a4 = coefs[4];
  174. a5 = coefs[5];
  175. a6 = coefs[6];
  176. a7 = coefs[7];
  177. for ( j = lim; j < num; j++ )
  178. {
  179. LOOP_ALIGN
  180. top = in[j - lim];
  181. pin = in + j - 1;
  182. b0 = top - (*pin--);
  183. b1 = top - (*pin--);
  184. b2 = top - (*pin--);
  185. b3 = top - (*pin--);
  186. b4 = top - (*pin--);
  187. b5 = top - (*pin--);
  188. b6 = top - (*pin--);
  189. b7 = top - (*pin);
  190. pin += 8;
  191. sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
  192. - a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift;
  193. del = in[j] - top - sum1;
  194. del = (del << chanshift) >> chanshift;
  195. pc1[j] = del;
  196. del0 = del;
  197. sg = sign_of_int(del);
  198. if ( sg > 0 )
  199. {
  200. sgn = sign_of_int( b7 );
  201. a7 -= sgn;
  202. del0 -= 1 * ((sgn * b7) >> denshift);
  203. if ( del0 <= 0 )
  204. continue;
  205. sgn = sign_of_int( b6 );
  206. a6 -= sgn;
  207. del0 -= 2 * ((sgn * b6) >> denshift);
  208. if ( del0 <= 0 )
  209. continue;
  210. sgn = sign_of_int( b5 );
  211. a5 -= sgn;
  212. del0 -= 3 * ((sgn * b5) >> denshift);
  213. if ( del0 <= 0 )
  214. continue;
  215. sgn = sign_of_int( b4 );
  216. a4 -= sgn;
  217. del0 -= 4 * ((sgn * b4) >> denshift);
  218. if ( del0 <= 0 )
  219. continue;
  220. sgn = sign_of_int( b3 );
  221. a3 -= sgn;
  222. del0 -= 5 * ((sgn * b3) >> denshift);
  223. if ( del0 <= 0 )
  224. continue;
  225. sgn = sign_of_int( b2 );
  226. a2 -= sgn;
  227. del0 -= 6 * ((sgn * b2) >> denshift);
  228. if ( del0 <= 0 )
  229. continue;
  230. sgn = sign_of_int( b1 );
  231. a1 -= sgn;
  232. del0 -= 7 * ((sgn * b1) >> denshift);
  233. if ( del0 <= 0 )
  234. continue;
  235. a0 -= sign_of_int( b0 );
  236. }
  237. else if ( sg < 0 )
  238. {
  239. // note: to avoid unnecessary negations, we flip the value of "sgn"
  240. sgn = -sign_of_int( b7 );
  241. a7 -= sgn;
  242. del0 -= 1 * ((sgn * b7) >> denshift);
  243. if ( del0 >= 0 )
  244. continue;
  245. sgn = -sign_of_int( b6 );
  246. a6 -= sgn;
  247. del0 -= 2 * ((sgn * b6) >> denshift);
  248. if ( del0 >= 0 )
  249. continue;
  250. sgn = -sign_of_int( b5 );
  251. a5 -= sgn;
  252. del0 -= 3 * ((sgn * b5) >> denshift);
  253. if ( del0 >= 0 )
  254. continue;
  255. sgn = -sign_of_int( b4 );
  256. a4 -= sgn;
  257. del0 -= 4 * ((sgn * b4) >> denshift);
  258. if ( del0 >= 0 )
  259. continue;
  260. sgn = -sign_of_int( b3 );
  261. a3 -= sgn;
  262. del0 -= 5 * ((sgn * b3) >> denshift);
  263. if ( del0 >= 0 )
  264. continue;
  265. sgn = -sign_of_int( b2 );
  266. a2 -= sgn;
  267. del0 -= 6 * ((sgn * b2) >> denshift);
  268. if ( del0 >= 0 )
  269. continue;
  270. sgn = -sign_of_int( b1 );
  271. a1 -= sgn;
  272. del0 -= 7 * ((sgn * b1) >> denshift);
  273. if ( del0 >= 0 )
  274. continue;
  275. a0 += sign_of_int( b0 );
  276. }
  277. }
  278. coefs[0] = a0;
  279. coefs[1] = a1;
  280. coefs[2] = a2;
  281. coefs[3] = a3;
  282. coefs[4] = a4;
  283. coefs[5] = a5;
  284. coefs[6] = a6;
  285. coefs[7] = a7;
  286. }
  287. else
  288. {
  289. //pc_block_general:
  290. // general case
  291. for ( j = lim; j < num; j++ )
  292. {
  293. LOOP_ALIGN
  294. top = in[j - lim];
  295. pin = in + j - 1;
  296. sum1 = 0;
  297. for ( k = 0; k < numactive; k++ )
  298. sum1 -= coefs[k] * (top - pin[-k]);
  299. del = in[j] - top - ((sum1 + denhalf) >> denshift);
  300. del = (del << chanshift) >> chanshift;
  301. pc1[j] = del;
  302. del0 = del;
  303. sg = sign_of_int( del );
  304. if ( sg > 0 )
  305. {
  306. for ( k = (numactive - 1); k >= 0; k-- )
  307. {
  308. dd = top - pin[-k];
  309. sgn = sign_of_int( dd );
  310. coefs[k] -= sgn;
  311. del0 -= (numactive - k) * ((sgn * dd) >> denshift);
  312. if ( del0 <= 0 )
  313. break;
  314. }
  315. }
  316. else if ( sg < 0 )
  317. {
  318. for ( k = (numactive - 1); k >= 0; k-- )
  319. {
  320. dd = top - pin[-k];
  321. sgn = sign_of_int( dd );
  322. coefs[k] += sgn;
  323. del0 -= (numactive - k) * ((-sgn * dd) >> denshift);
  324. if ( del0 >= 0 )
  325. break;
  326. }
  327. }
  328. }
  329. }
  330. }