idct_c.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:11k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: idct_c.c 323 2005-11-01 20:52:32Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "softidct.h"
  25. #define W1 2841  // 2048*sqrt(2)*cos(1*pi/16) 
  26. #define W2 2676  // 2048*sqrt(2)*cos(2*pi/16) 
  27. #define W3 2408  // 2048*sqrt(2)*cos(3*pi/16) 
  28. #define W5 1609  // 2048*sqrt(2)*cos(5*pi/16) 
  29. #define W6 1108  // 2048*sqrt(2)*cos(6*pi/16) 
  30. #define W7 565   // 2048*sqrt(2)*cos(7*pi/16) 
  31. #define ADDSAT32(a,Dst,Add32)
  32. b = a + Add32;
  33. c = a & Add32;
  34. a ^= Add32;
  35. a &= ~b;
  36. a |= c;
  37. a &= MaskCarry;
  38. c = a << 1;
  39. b -= c; /* adjust neighbour */
  40. b |= c - (a >> 7); /* mask */
  41. Dst = b;
  42. #define SUBSAT32(a,Dst,Add32)
  43. a = ~a;
  44. b = a + Add32;
  45. c = a & Add32;
  46. a ^= Add32;
  47. a &= ~b;
  48. a |= c;
  49. a &= MaskCarry;
  50. c = a << 1;
  51. b -= c; /* adjust neighbour */
  52. b |= c - (a >> 7); /* mask */
  53. Dst = ~b;
  54. #if !defined(ARM) 
  55. #define SPLIT(d0,d1,d2)
  56. d0 = d1 + d2;
  57. d1 -= d2;
  58. #define BUTTERFLY(d0,d1,W0,W1,tmp)
  59.     tmp = W0 * (d0 + d1);
  60.     d0 = tmp + (W1 - W0) * d0;
  61.     d1 = tmp - (W1 + W0) * d1;
  62. #ifdef MIPSVR41XX
  63. #define WRITEBACK(Dst,n)
  64. __asm(  "andi $7,%0,0x8;"
  65. "beq $7,$0, skipwb" #n ";" 
  66. ".set noreorder;"
  67. "cache 25,-8(%0);"
  68. ".set reorder;"
  69. "skipwb" #n ":",Dst);
  70. #else
  71. #define WRITEBACK(Dst,n)
  72. #endif
  73. static void IDCT_Col8(idct_block_t *Blk)
  74. {
  75. int d0,d1,d2,d3,d4,d5,d6,d7,d8;
  76. d0 = Blk[0];
  77. d4 = Blk[8];
  78. d3 = Blk[16];
  79. d7 = Blk[24];
  80. d1 = Blk[32];
  81. d6 = Blk[40];
  82. d2 = Blk[48];
  83. d5 = Blk[56];
  84. d8 = d5|d6|d7;
  85. if (!(d1|d2|d3|d8))
  86. {
  87. if (!d4) 
  88. // d0
  89. if (d0) 
  90. {
  91. d0 <<= 3;
  92. Blk[0]  = (idct_block_t)d0;
  93. Blk[8]  = (idct_block_t)d0;
  94. Blk[16] = (idct_block_t)d0;
  95. Blk[24] = (idct_block_t)d0;
  96. Blk[32] = (idct_block_t)d0;
  97. Blk[40] = (idct_block_t)d0;
  98. Blk[48] = (idct_block_t)d0;
  99. Blk[56] = (idct_block_t)d0;
  100. }
  101. }
  102. else 
  103. // d0,d4
  104. d0 = (d0 << 11) + 128; //+final rounding
  105. //d1 = (d1 << 11);
  106. d1 = W7 * d4;
  107. d2 = W1 * d4;
  108. d3 = W3 * d4;
  109. d4 = W5 * d4;
  110. Blk[0]  = (idct_block_t)((d0 + d2) >> 8);
  111. Blk[8]  = (idct_block_t)((d0 + d3) >> 8);
  112. Blk[16] = (idct_block_t)((d0 + d4) >> 8);
  113. Blk[24] = (idct_block_t)((d0 + d1) >> 8);
  114. Blk[32] = (idct_block_t)((d0 - d1) >> 8);
  115. Blk[40] = (idct_block_t)((d0 - d4) >> 8);
  116. Blk[48] = (idct_block_t)((d0 - d3) >> 8);
  117. Blk[56] = (idct_block_t)((d0 - d2) >> 8);
  118. }
  119. }
  120. else if (!(d4|d8)) 
  121. // d0,d1,d2,d3
  122. d0 = (d0 << 11) + 128; //+final rounding
  123. d1 = (d1 << 11);
  124. SPLIT(d4,d0,d1) //d1->d4
  125. BUTTERFLY(d3,d2,W6,W2,d1)
  126. SPLIT(d5,d4,d3) //d3->d5
  127. SPLIT(d3,d0,d2) //d2->d3
  128. Blk[0]  = (idct_block_t)(d5 >> 8);
  129. Blk[8]  = (idct_block_t)(d3 >> 8);
  130. Blk[16] = (idct_block_t)(d0 >> 8);
  131. Blk[24] = (idct_block_t)(d4 >> 8);
  132. Blk[32] = (idct_block_t)(d4 >> 8);
  133. Blk[40] = (idct_block_t)(d0 >> 8);
  134. Blk[48] = (idct_block_t)(d3 >> 8);
  135. Blk[56] = (idct_block_t)(d5 >> 8);
  136. }
  137. else 
  138. // d0,d1,d2,d3,d4,d5,d6,d7
  139. d0 = (d0 << 11) + 128; //+final rounding
  140. d1 = (d1 << 11);
  141. BUTTERFLY(d4,d5,W7,W1,d8)
  142. BUTTERFLY(d6,d7,W3,W5,d8)
  143. SPLIT(d8,d0,d1) //d1->d8
  144. BUTTERFLY(d3,d2,W6,W2,d1)
  145. SPLIT(d1,d4,d6) //d6->d1
  146. SPLIT(d6,d5,d7) //d7->d6
  147. SPLIT(d7,d8,d3) //d3->d7
  148. SPLIT(d3,d0,d2) //d2->d3
  149. d2 = (181 * (d4+d5) + 128) >> 8;
  150. d4 = (181 * (d4-d5) + 128) >> 8;
  151. Blk[0]  = (idct_block_t)((d7 + d1) >> 8);
  152. Blk[8]  = (idct_block_t)((d3 + d2) >> 8);
  153. Blk[16] = (idct_block_t)((d0 + d4) >> 8);
  154. Blk[24] = (idct_block_t)((d8 + d6) >> 8);
  155. Blk[32] = (idct_block_t)((d8 - d6) >> 8);
  156. Blk[40] = (idct_block_t)((d0 - d4) >> 8);
  157. Blk[48] = (idct_block_t)((d3 - d2) >> 8);
  158. Blk[56] = (idct_block_t)((d7 - d1) >> 8);
  159. }
  160. }
  161. static void IDCT_Row8(idct_block_t *Blk, uint8_t *Dst, const uint8_t *Src)
  162. {
  163. int d0,d1,d2,d3,d4,d5,d6,d7,d8;
  164. d4 = Blk[1];
  165.    d3 = Blk[2];
  166.    d7 = Blk[3];
  167. d1 = Blk[4];
  168. d6 = Blk[5];
  169. d2 = Blk[6];
  170. d5 = Blk[7];
  171. if (!(d1|d2|d3|d4|d5|d6|d7))
  172. {
  173. d0 = (Blk[0] + 32) >> 6;
  174. if (!Src)
  175. {
  176. SAT(d0);
  177. d0 &= 255;
  178. d0 |= d0 << 8;
  179. d0 |= d0 << 16;
  180. ((uint32_t*)Dst)[0] = d0;
  181. ((uint32_t*)Dst)[1] = d0;
  182. WRITEBACK(Dst,0);
  183. return;
  184. }
  185. d1 = d2 = d3 = d4 = d5 = d6 = d7 = d0;
  186. }
  187. else
  188. {
  189. d0 = (Blk[0] << 11) + 65536; // +final rounding
  190. d1 <<= 11;
  191. BUTTERFLY(d4,d5,W7,W1,d8)
  192. BUTTERFLY(d6,d7,W3,W5,d8)
  193. SPLIT(d8,d0,d1) //d1->d8
  194. BUTTERFLY(d3,d2,W6,W2,d1)
  195. SPLIT(d1,d4,d6) //d6->d1
  196. SPLIT(d6,d5,d7) //d7->d6
  197. SPLIT(d7,d8,d3) //d3->d7
  198. SPLIT(d3,d0,d2) //d2->d3
  199. d2 = 181 * ((d4 + d5 + 128) >> 8);
  200. d4 = 181 * ((d4 - d5 + 128) >> 8);
  201. d5 = (d7 + d1) >> 17;
  202. d1 = (d7 - d1) >> 17;
  203. d7 = (d3 + d2) >> 17;
  204. d2 = (d3 - d2) >> 17;
  205. d3 = (d0 + d4) >> 17;
  206. d4 = (d0 - d4) >> 17;
  207. d0 = (d8 + d6) >> 17;
  208. d6 = (d8 - d6) >> 17;
  209. }
  210. if (Src)
  211. {
  212. d5 += Src[0];
  213. d1 += Src[7];
  214. d7 += Src[1];
  215. d2 += Src[6];
  216. d3 += Src[2];
  217. d4 += Src[5];
  218. d0 += Src[3];
  219. d6 += Src[4];
  220. }
  221. if ((d5|d1|d7|d2|d3|d4|d0|d6)>>8)
  222. {
  223. SAT(d5)
  224. SAT(d7)
  225. SAT(d3)
  226. SAT(d0)
  227. SAT(d6)
  228. SAT(d4)
  229. SAT(d2)
  230. SAT(d1)
  231. }
  232. Dst[0] = (uint8_t)d5;
  233. Dst[1] = (uint8_t)d7;
  234. Dst[2] = (uint8_t)d3;
  235. Dst[3] = (uint8_t)d0;
  236. Dst[4] = (uint8_t)d6;
  237. Dst[5] = (uint8_t)d4;
  238. Dst[6] = (uint8_t)d2;
  239. Dst[7] = (uint8_t)d1;
  240. WRITEBACK(Dst,1);
  241. }
  242. static void IDCT_Row4(idct_block_t *Blk, uint8_t *Dst, const uint8_t *Src)
  243. {
  244. int d0,d1,d2,d3,d4,d5,d6,d7,d8;
  245.   
  246. d4 = Blk[1];
  247.    d3 = Blk[2];
  248.    d7 = Blk[3];
  249. if (!(d3|d4|d7))
  250. {
  251. d0 = (Blk[0] + 32) >> 6;
  252. if (!Src)
  253. {
  254. SAT(d0);
  255. d0 &= 255;
  256. d0 |= d0 << 8;
  257. d0 |= d0 << 16;
  258. ((uint32_t*)Dst)[0] = d0;
  259. ((uint32_t*)Dst)[1] = d0;
  260. WRITEBACK(Dst,2);
  261. return;
  262. }
  263. d1 = d2 = d3 = d4 = d5 = d6 = d7 = d0;
  264. }
  265. else
  266. {
  267. d0 = (Blk[0] << 11) + 65536; // +final rounding
  268. d5 = W7 * d4;
  269. d4 = W1 * d4;
  270. d6 = W3 * d7;
  271. d7 = -W5 * d7;
  272. d2 = W6 * d3;
  273. d3 = W2 * d3;
  274. SPLIT(d1,d4,d6)
  275. SPLIT(d6,d5,d7)
  276. d8 = d0;
  277. SPLIT(d7,d8,d3)
  278. SPLIT(d3,d0,d2)
  279. d2 = 181 * ((d4 + d5 + 128) >> 8);
  280. d4 = 181 * ((d4 - d5 + 128) >> 8);
  281. d5 = (d7 + d1) >> 17;
  282. d1 = (d7 - d1) >> 17;
  283. d7 = (d3 + d2) >> 17;
  284. d2 = (d3 - d2) >> 17;
  285. d3 = (d0 + d4) >> 17;
  286. d4 = (d0 - d4) >> 17;
  287. d0 = (d8 + d6) >> 17;
  288. d6 = (d8 - d6) >> 17;
  289. }
  290. if (Src)
  291. {
  292. d5 += Src[0];
  293. d1 += Src[7];
  294. d7 += Src[1];
  295. d2 += Src[6];
  296. d3 += Src[2];
  297. d4 += Src[5];
  298. d0 += Src[3];
  299. d6 += Src[4];
  300. }
  301. if ((d5|d1|d7|d2|d3|d4|d0|d6)>>8)
  302. {
  303. SAT(d5)
  304. SAT(d7)
  305. SAT(d3)
  306. SAT(d0)
  307. SAT(d6)
  308. SAT(d4)
  309. SAT(d2)
  310. SAT(d1)
  311. }
  312. Dst[0] = (uint8_t)d5;
  313. Dst[1] = (uint8_t)d7;
  314. Dst[2] = (uint8_t)d3;
  315. Dst[3] = (uint8_t)d0;
  316. Dst[4] = (uint8_t)d6;
  317. Dst[5] = (uint8_t)d4;
  318. Dst[6] = (uint8_t)d2;
  319. Dst[7] = (uint8_t)d1;
  320. WRITEBACK(Dst,3);
  321. }
  322. void STDCALL IDCT_Block8x8(idct_block_t *Block, uint8_t *Dest, int DestStride, const uint8_t *Src)
  323. {
  324. int SrcStride;
  325. IDCT_Col8(Block);
  326. IDCT_Col8(Block+1);
  327. IDCT_Col8(Block+2);
  328. IDCT_Col8(Block+3);
  329. IDCT_Col8(Block+4);
  330. IDCT_Col8(Block+5);
  331. IDCT_Col8(Block+6);
  332. IDCT_Col8(Block+7);
  333. SrcStride = 0;
  334. #ifdef MIPS64
  335. if (Src) SrcStride = DestStride;
  336. #else
  337. if (Src) SrcStride = 8;
  338. #endif
  339. IDCT_Row8(Block,Dest,Src);
  340. Dest+=DestStride;
  341. Src+=SrcStride;
  342. IDCT_Row8(Block+8,Dest,Src);
  343. Dest+=DestStride;
  344. Src+=SrcStride;
  345. IDCT_Row8(Block+16,Dest,Src);
  346. Dest+=DestStride;
  347. Src+=SrcStride;
  348. IDCT_Row8(Block+24,Dest,Src);
  349. Dest+=DestStride;
  350. Src+=SrcStride;
  351. IDCT_Row8(Block+32,Dest,Src);
  352. Dest+=DestStride;
  353. Src+=SrcStride;
  354. IDCT_Row8(Block+40,Dest,Src);
  355. Dest+=DestStride;
  356. Src+=SrcStride;
  357. IDCT_Row8(Block+48,Dest,Src);
  358. Dest+=DestStride;
  359. Src+=SrcStride;
  360. IDCT_Row8(Block+56,Dest,Src);
  361. }
  362. void STDCALL IDCT_Block4x8(idct_block_t *Block, uint8_t *Dest, int DestStride, const uint8_t *Src)
  363. {
  364. int SrcStride;
  365. IDCT_Col8(Block);
  366. IDCT_Col8(Block+1);
  367. IDCT_Col8(Block+2);
  368. IDCT_Col8(Block+3);
  369. SrcStride = 0;
  370. #ifdef MIPS64
  371. if (Src) SrcStride = DestStride;
  372. #else
  373. if (Src) SrcStride = 8;
  374. #endif
  375. IDCT_Row4(Block,Dest,Src);
  376. Dest+=DestStride;
  377. Src+=SrcStride;
  378. IDCT_Row4(Block+8,Dest,Src);
  379. Dest+=DestStride;
  380. Src+=SrcStride;
  381. IDCT_Row4(Block+16,Dest,Src);
  382. Dest+=DestStride;
  383. Src+=SrcStride;
  384. IDCT_Row4(Block+24,Dest,Src);
  385. Dest+=DestStride;
  386. Src+=SrcStride;
  387. IDCT_Row4(Block+32,Dest,Src);
  388. Dest+=DestStride;
  389. Src+=SrcStride;
  390. IDCT_Row4(Block+40,Dest,Src);
  391. Dest+=DestStride;
  392. Src+=SrcStride;
  393. IDCT_Row4(Block+48,Dest,Src);
  394. Dest+=DestStride;
  395. Src+=SrcStride;
  396. IDCT_Row4(Block+56,Dest,Src);
  397. }
  398. #ifdef CONFIG_IDCT_SWAP
  399. // just for testing
  400. void STDCALL IDCT_Block4x8Swap(idct_block_t *Block, uint8_t *Dest, int DestStride, const uint8_t *Src)
  401. {
  402. int x;
  403. for (x=0;x<64;++x)
  404. Block[64+x] = Block[((x&7)<<3)+(x>>3)];
  405. IDCT_Block4x8(Block+64,Dest,DestStride,Src);
  406. }
  407. void STDCALL IDCT_Block8x8Swap(idct_block_t *Block, uint8_t *Dest, int DestStride, const uint8_t *Src)
  408. {
  409. int x;
  410. for (x=0;x<64;++x)
  411. Block[64+x] = Block[((x&7)<<3)+(x>>3)];
  412. IDCT_Block8x8(Block+64,Dest,DestStride,Src);
  413. }
  414. #endif
  415. #endif
  416. #ifndef MMX
  417. void STDCALL IDCT_Const8x8(int v,uint8_t * Dst, int DstPitch, uint8_t * Src)
  418. {
  419. #ifndef MIPS64
  420. int SrcPitch = 8;
  421. #else
  422. int SrcPitch = DstPitch;
  423. #endif
  424. const uint8_t* SrcEnd = Src + 8*SrcPitch;
  425. uint32_t MaskCarry = 0x80808080U;
  426. uint32_t a,b,c,d;
  427. if (v>0)
  428. {
  429. v |= v << 8;
  430. v |= v << 16;
  431. do
  432. {
  433. a = ((uint32_t*)Src)[0];
  434. d = ((uint32_t*)Src)[1];
  435. ADDSAT32(a,((uint32_t*)Dst)[0],v);
  436. ADDSAT32(d,((uint32_t*)Dst)[1],v);
  437. Dst += DstPitch;
  438. Src += SrcPitch;
  439. }
  440. while (Src != SrcEnd);
  441. }
  442. else
  443. if (v<0)
  444. {
  445. v = -v;
  446. v |= v << 8;
  447. v |= v << 16;
  448. do
  449. {
  450. a = ((uint32_t*)Src)[0];
  451. d = ((uint32_t*)Src)[1];
  452. SUBSAT32(a,((uint32_t*)Dst)[0],v);
  453. SUBSAT32(d,((uint32_t*)Dst)[1],v);
  454. Dst += DstPitch;
  455. Src += SrcPitch;
  456. }
  457. while (Src != SrcEnd);
  458. }
  459. #ifndef MIPS64
  460. else
  461. CopyBlock8x8(Src,Dst,SrcPitch,DstPitch);
  462. #endif
  463. }
  464. #endif