postprocess.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:17k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "postprocess.h"
  2. #ifdef PP_SELF_CHECK
  3. #include <stdio.h>
  4. #endif
  5. #define ABS(a)     ( (a)>0 ? (a) : -(a) )
  6. #define SIGN(a)    ( (a)<0 ? -1 : 1 )
  7. #define MIN(a, b)  ( (a)<(b) ? (a) : (b) )
  8. #define MAX(a, b)  ( (a)>(b) ? (a) : (b) )
  9. static int deblock_horiz_useDC(uint8_t *v, int stride) {
  10. int eq_cnt, useDC;
  11. int x, y;
  12. #ifdef PP_SELF_CHECK
  13. int eq_cnt2, j, k;
  14. #endif
  15. eq_cnt = 0;
  16. for (y=0; y<4; y++) {
  17. for (x=1; x<=7; x++) {
  18. if (ABS(v[x+y*stride]-v[1+x+y*stride]) <= 1) eq_cnt--;
  19. }
  20. }
  21. #ifdef PP_SELF_CHECK
  22. eq_cnt2 = 0;
  23. for (k=0; k<4; k++) {
  24. for (j=1; j<=7; j++) {
  25. if (ABS(v[j+k*stride]-v[1+j+k*stride]) <= 1) eq_cnt2--;
  26. }
  27. }
  28. if (eq_cnt2 != eq_cnt) printf("ERROR: C version of useDC is incorrectn");
  29. #endif
  30. useDC = eq_cnt <= -DEBLOCK_HORIZ_USEDC_THR;
  31. return useDC;
  32. }
  33. static int deblock_horiz_DC_on(uint8_t *v, int stride, int QP) {
  34. return (ABS(v[1]-v[8]) < 2*QP);
  35. }
  36. static void deblock_horiz_lpf9(uint8_t *v, int stride, int QP) {
  37. int x, y, p1, p2, psum;
  38. uint8_t *vv, vnew[9];
  39. #ifdef PP_SELF_CHECK
  40. uint8_t selfcheck[9];
  41. int psum2;
  42. uint8_t *vv2; 
  43. #endif
  44. for (y=0; y<4; y++) {
  45. p1 = (ABS(v[0+y*stride]-v[1+y*stride]) < QP ) ?  v[0+y*stride] : v[1+y*stride];
  46. p2 = (ABS(v[8+y*stride]-v[9+y*stride]) < QP ) ?  v[9+y*stride] : v[8+y*stride];
  47. #ifdef PP_SELF_CHECK
  48. vv2 = &(v[y*stride]);
  49. psum2 = p1 + p1 + p1 + vv2[1] + vv2[2] + vv2[3] + vv2[4] + 4;
  50. selfcheck[1] = (((psum2 + vv2[1]) << 1) - (vv2[4] - vv2[5])) >> 4;
  51. psum2 += vv2[5] - p1; 
  52. selfcheck[2] = (((psum2 + vv2[2]) << 1) - (vv2[5] - vv2[6])) >> 4;
  53. psum2 += vv2[6] - p1; 
  54. selfcheck[3] = (((psum2 + vv2[3]) << 1) - (vv2[6] - vv2[7])) >> 4;
  55. psum2 += vv2[7] - p1; 
  56. selfcheck[4] = (((psum2 + vv2[4]) << 1) + p1 - vv2[1] - (vv2[7] - vv2[8])) >> 4;
  57. psum2 += vv2[8] - vv2[1]; 
  58. selfcheck[5] = (((psum2 + vv2[5]) << 1) + (vv2[1] - vv2[2]) - vv2[8] + p2) >> 4;
  59. psum2 += p2 - vv2[2]; 
  60. selfcheck[6] = (((psum2 + vv2[6]) << 1) + (vv2[2] - vv2[3])) >> 4;
  61. psum2 += p2 - vv2[3]; 
  62. selfcheck[7] = (((psum2 + vv2[7]) << 1) + (vv2[3] - vv2[4])) >> 4;
  63. psum2 += p2 - vv2[4]; 
  64. selfcheck[8] = (((psum2 + vv2[8]) << 1) + (vv2[4] - vv2[5])) >> 4;
  65. #endif
  66. vv = &(v[y*stride]);
  67. psum = p1 + p1 + p1 + vv[1] + vv[2] + vv[3] + vv[4] + 4;
  68. vnew[1] = (((psum + vv[1]) << 1) - (vv[4] - vv[5])) >> 4;
  69. psum += vv[5] - p1; 
  70. vnew[2] = (((psum + vv[2]) << 1) - (vv[5] - vv[6])) >> 4;
  71. psum += vv[6] - p1; 
  72. vnew[3] = (((psum + vv[3]) << 1) - (vv[6] - vv[7])) >> 4;
  73. psum += vv[7] - p1; 
  74. vnew[4] = (((psum + vv[4]) << 1) + p1 - vv[1] - (vv[7] - vv[8])) >> 4;
  75. psum += vv[8] - vv[1]; 
  76. vnew[5] = (((psum + vv[5]) << 1) + (vv[1] - vv[2]) - vv[8] + p2) >> 4;
  77. psum += p2 - vv[2]; 
  78. vnew[6] = (((psum + vv[6]) << 1) + (vv[2] - vv[3])) >> 4;
  79. psum += p2 - vv[3]; 
  80. vnew[7] = (((psum + vv[7]) << 1) + (vv[3] - vv[4])) >> 4;
  81. psum += p2 - vv[4]; 
  82. vnew[8] = (((psum + vv[8]) << 1) + (vv[4] - vv[5])) >> 4;
  83. for (x=1; x<=8; x++) {
  84. vv[x] = vnew[x];
  85. }
  86. #ifdef PP_SELF_CHECK
  87. for (x=1; x<=8; x++) {
  88. if (selfcheck[x] != v[x+y*stride]) printf("ERROR: C version of horiz lpf9 is incorrectn");
  89. }
  90. #endif
  91. }
  92. }
  93. static void deblock_horiz_default_filter(uint8_t *v, int stride, int QP) {
  94. int a3_0, a3_1, a3_2, d;
  95. int q1, q;
  96. int y;
  97. for (y=0; y<4; y++) {
  98. q1 = v[4] - v[5];
  99. q = q1 / 2;
  100. if (q) {
  101. a3_0 = 2*(v[3]-v[6]) - 5*q1;
  102. if (ABS(a3_0) < 8*QP) {
  103. a3_1 = 2*(v[1]-v[4]) + 5*(v[3]-v[2]);
  104. a3_2 = 2*(v[5]-v[8]) + 5*(v[7]-v[8]);
  105. d = ABS(a3_0) - MIN(ABS(a3_1), ABS(a3_2));
  106. if (d > 0) { 
  107. d += d<<2;
  108. d = (d + 32) >> 6; 
  109. if (d > 0) {
  110. d *= SIGN(-a3_0);
  111. if (q > 0) {
  112. d = d<0 ? 0 : d;
  113. d = d>q ? q : d;
  114. } else {
  115. d = d>0 ? 0 : d;
  116. d = d<q ? q : d;
  117. }
  118. v[4] -= d;
  119. v[5] += d;
  120. }
  121. }
  122. }
  123. }
  124. #ifdef PP_SELF_CHECK
  125. #endif;
  126. v += stride;
  127. }
  128. }
  129. void deblock_horiz(uint8_t *image, int width, int height, int stride, QP_STORE_T *QP_store, int QP_stride, int chroma) {
  130. int x, y;
  131. int QP;
  132. uint8_t *v;
  133. int useDC, DC_on;
  134. for (y=0; y<height; y+=4) {
  135. for (x=8; x<width; x+=8) {
  136. QP = chroma ? QP_store[y/8*QP_stride+x/8]
  137.                 : QP_store[y/16*QP_stride+x/16];
  138. v = &(image[y*stride + x]) - 5;
  139. useDC = deblock_horiz_useDC(v, stride);
  140. if (useDC) { 
  141. DC_on = deblock_horiz_DC_on(v, stride, QP);
  142. if (DC_on) {
  143. deblock_horiz_lpf9(v, stride, QP); 
  144. #ifdef SHOWDECISIONS_H
  145. if (!chromaFlag) {
  146. v[0*stride + 4] = 
  147. v[1*stride + 4] = 
  148. v[2*stride + 4] = 
  149. v[3*stride + 4] = 255;  
  150. }
  151. #endif
  152. }
  153. } else {     
  154. deblock_horiz_default_filter(v, stride, QP);
  155. #ifdef SHOWDECISIONS_H
  156. if (!chromaFlag) {
  157. v[0*stride + 4] = 
  158. v[1*stride + 4] = 
  159. v[2*stride + 4] = 
  160. v[3*stride + 4] = 0;  
  161. }
  162. #endif
  163. }
  164. }
  165. }
  166. }
  167. static int deblock_vert_useDC(uint8_t *v, int stride) {
  168. int eq_cnt, useDC, x, y;
  169. #ifdef PP_SELF_CHECK
  170. int useDC2, j, i;
  171. #endif
  172. #ifdef PP_SELF_CHECK
  173. eq_cnt = 0;
  174. for (j=1; j<8; j++) {
  175. for (i=0; i<8; i++) {
  176. if (ABS(v[j*stride+i] - v[(j+1)*stride+i]) <= 1) eq_cnt++;
  177. }
  178. }
  179. useDC2 = (eq_cnt > DEBLOCK_VERT_USEDC_THR); 
  180. #endif
  181. eq_cnt = 0;
  182. for (y=1; y<8; y++) {
  183. for (x=0; x<8; x++) {
  184. if (ABS(v[y*stride+x] - v[(y+1)*stride+x]) <= 1) eq_cnt++;
  185. }
  186. }
  187. useDC = (eq_cnt  > DEBLOCK_VERT_USEDC_THR);
  188. #ifdef PP_SELF_CHECK
  189. if (useDC != useDC2) printf("ERROR: C version of useDC is incorrectn");
  190. #endif
  191. return useDC;
  192. }
  193. static int deblock_vert_DC_on(uint8_t *v, int stride, int QP) {
  194. int DC_on, x;
  195. #ifdef PP_SELF_CHECK
  196. int i, DC_on2;
  197. #endif
  198. #ifdef PP_SELF_CHECK
  199. DC_on2 = 1;
  200. for (i=0; i<8; i++) {
  201. if (ABS(v[i+1*stride]-v[i+8*stride]) > 2 *QP) DC_on2 = 0;
  202. }
  203. #endif
  204. DC_on = 1;
  205. for (x=0; x<8; x++) {
  206. if (ABS(v[x+1*stride]-v[x+8*stride]) > 2 *QP) DC_on = 0;
  207. }
  208. #ifdef PP_SELF_CHECK
  209. if (DC_on != DC_on2) printf("ERROR: C version of DC_on is incorrectn");
  210. #endif
  211. return DC_on;
  212. }
  213. void deblock_vert_lpf9(uint64_t *v_local, uint64_t *p1p2, uint8_t *v, int stride, int QP) {
  214. int x, y;
  215. int p1, p2, psum;
  216. uint8_t  *vv, vnew[9];
  217. int l1 = 1 * stride;
  218. int l2 = 2 * stride;
  219. int l3 = 3 * stride;
  220. int l4 = 4 * stride;
  221. int l5 = 5 * stride;
  222. int l6 = 6 * stride;
  223. int l7 = 7 * stride;
  224. int l8 = 8 * stride;
  225. #ifdef PP_SELF_CHECK
  226. int j, k;
  227. uint8_t selfcheck[64];
  228. #endif
  229. #ifdef PP_SELF_CHECK
  230. for (j=0; j<8; j++) { 
  231. vv = &(v[j]);
  232. p1 = (ABS(vv[0*stride]-vv[1*stride]) < QP ) ?  vv[0*stride] : vv[1*stride];
  233. p2 = (ABS(vv[8*stride]-vv[9*stride]) < QP ) ?  vv[9*stride] : vv[8*stride];
  234. psum = p1 + p1 + p1 + vv[l1] + vv[l2] + vv[l3] + vv[l4] + 4; 
  235. selfcheck[j+8*0] = (((psum + vv[l1]) << 1) - (vv[l4] - vv[l5])) >> 4; 
  236. psum += vv[l5] - p1; 
  237. selfcheck[j+8*1] = (((psum + vv[l2]) << 1) - (vv[l5] - vv[l6])) >> 4; 
  238. psum += vv[l6] - p1; 
  239. selfcheck[j+8*2] = (((psum + vv[l3]) << 1) - (vv[l6] - vv[l7])) >> 4; 
  240. psum += vv[l7] - p1; 
  241. selfcheck[j+8*3] = (((psum + vv[l4]) << 1) + p1 - vv[l1] - (vv[l7] - vv[l8])) >> 4; 
  242. psum += vv[l8] - vv[l1];  
  243. selfcheck[j+8*4] = (((psum + vv[l5]) << 1) + (vv[l1] - vv[l2]) - vv[l8] + p2) >> 4; 
  244. psum += p2 - vv[l2];  
  245. selfcheck[j+8*5] = (((psum + vv[l6]) << 1) + (vv[l2] - vv[l3])) >> 4; 
  246. psum += p2 - vv[l3]; 
  247. selfcheck[j+8*6] = (((psum + vv[l7]) << 1) + (vv[l3] - vv[l4])) >> 4; 
  248. psum += p2 - vv[l4]; 
  249. selfcheck[j+8*7] = (((psum + vv[l8]) << 1) + (vv[l4] - vv[l5])) >> 4; 
  250. }
  251. #endif
  252. for (x=0; x<8; x++) { 
  253. vv = &(v[x]);
  254. p1 = (ABS(vv[0*stride]-vv[1*stride]) < QP ) ?  vv[0*stride] : vv[1*stride];
  255. p2 = (ABS(vv[8*stride]-vv[9*stride]) < QP ) ?  vv[9*stride] : vv[8*stride];
  256. psum = p1 + p1 + p1 + vv[l1] + vv[l2] + vv[l3] + vv[l4] + 4; 
  257. vnew[1] = (((psum + vv[l1]) << 1) - (vv[l4] - vv[l5])) >> 4; 
  258. psum += vv[l5] - p1; 
  259. vnew[2] = (((psum + vv[l2]) << 1) - (vv[l5] - vv[l6])) >> 4; 
  260. psum += vv[l6] - p1; 
  261. vnew[3] = (((psum + vv[l3]) << 1) - (vv[l6] - vv[l7])) >> 4; 
  262. psum += vv[l7] - p1; 
  263. vnew[4] = (((psum + vv[l4]) << 1) + p1 - vv[l1] - (vv[l7] - vv[l8])) >> 4; 
  264. psum += vv[l8] - vv[l1];  
  265. vnew[5] = (((psum + vv[l5]) << 1) + (vv[l1] - vv[l2]) - vv[l8] + p2) >> 4; 
  266. psum += p2 - vv[l2];  
  267. vnew[6] = (((psum + vv[l6]) << 1) + (vv[l2] - vv[l3])) >> 4; 
  268. psum += p2 - vv[l3]; 
  269. vnew[7] = (((psum + vv[l7]) << 1) + (vv[l3] - vv[l4])) >> 4; 
  270. psum += p2 - vv[l4]; 
  271. vnew[8] = (((psum + vv[l8]) << 1) + (vv[l4] - vv[l5])) >> 4;
  272. for (y=1; y<=8; y++) {
  273. vv[y*stride] = vnew[y];
  274. }  
  275. }
  276. #ifdef PP_SELF_CHECK
  277. for (k=0; k<8; k++) {
  278. for (j=0; j<8; j++) { 
  279. if (v[(k+1)*stride + j] != selfcheck[j+8*k]) printf("ERROR: problem with C filter in row %dn", k+1);
  280. }
  281. }
  282. #endif
  283. }
  284. static void deblock_vert_default_filter(uint8_t *v, int stride, int QP) {
  285. int x, a3_0, a3_1, a3_2, d, q;
  286. int l1 = 1 * stride;
  287. int l2 = 2 * stride;
  288. int l3 = 3 * stride;
  289. int l4 = 4 * stride;
  290. int l5 = 5 * stride;
  291. int l6 = 6 * stride;
  292. int l7 = 7 * stride;
  293. int l8 = 8 * stride;
  294. #ifdef PP_SELF_CHECK
  295. int j, k, a3_0_SC, a3_1_SC, a3_2_SC, d_SC, q_SC;
  296. uint8_t selfcheck[8][2];
  297. #endif
  298. #ifdef PP_SELF_CHECK
  299. for (j=0; j<8; j++) {
  300. a3_0_SC = 2*v[l3+j] - 5*v[l4+j] + 5*v[l5+j] - 2*v[l6+j];
  301. a3_1_SC = 2*v[l1+j] - 5*v[l2+j] + 5*v[l3+j] - 2*v[l4+j];
  302. a3_2_SC = 2*v[l5+j] - 5*v[l6+j] + 5*v[l7+j] - 2*v[l8+j];
  303. q_SC    = (v[l4+j] - v[l5+j]) / 2;
  304. if (ABS(a3_0_SC) < 8*QP) {
  305. d_SC = ABS(a3_0_SC) - MIN(ABS(a3_1_SC), ABS(a3_2_SC));
  306. if (d_SC < 0) d_SC=0;
  307. d_SC = (5*d_SC + 32) >> 6; 
  308. d_SC *= SIGN(-a3_0_SC);
  309. if (q_SC > 0) {
  310. d_SC = d_SC<0    ? 0    : d_SC;
  311. d_SC = d_SC>q_SC ? q_SC : d_SC;
  312. } else {
  313. d_SC = d_SC>0    ? 0    : d_SC;
  314. d_SC = d_SC<q_SC ? q_SC : d_SC;
  315. }
  316. } else {
  317. d_SC = 0;
  318. }
  319. selfcheck[j][0] = v[l4+j] - d_SC;
  320. selfcheck[j][1] = v[l5+j] + d_SC;
  321. }
  322. #endif
  323. for (x=0; x<8; x++) {
  324. a3_0 = 2*v[l3+x] - 5*v[l4+x] + 5*v[l5+x] - 2*v[l6+x];
  325. a3_1 = 2*v[l1+x] - 5*v[l2+x] + 5*v[l3+x] - 2*v[l4+x];
  326. a3_2 = 2*v[l5+x] - 5*v[l6+x] + 5*v[l7+x] - 2*v[l8+x];
  327. q    = (v[l4+x] - v[l5+x]) / 2;
  328. if (ABS(a3_0) < 8*QP) {
  329. d = ABS(a3_0) - MIN(ABS(a3_1), ABS(a3_2));
  330. if (d < 0) d=0;
  331. d = (5*d + 32) >> 6; 
  332. d *= SIGN(-a3_0);
  333. if (q > 0) {
  334. d = d<0    ? 0    : d;
  335. d = d>q ? q : d;
  336. } else {
  337. d = d>0    ? 0    : d;
  338. d = d<q ? q : d;
  339. }
  340. } else {
  341. d = 0;
  342. }
  343. v[l4+x] -= d;
  344. v[l5+x] += d;
  345. }
  346. #ifdef PP_SELF_CHECK
  347. for (j=0; j<8; j++) {
  348. for (k=0; k<2; k++) {
  349. if (selfcheck[j][k] != v[l4+j+k*stride]) {
  350. printf("ERROR: problem with vertical default filter in col %d, row %dn", j, k);
  351. printf("%d should be %dn", v[l4+j+k*stride], selfcheck[j][k]);
  352. }
  353. }
  354. }
  355. #endif
  356. }
  357. void deblock_vert( uint8_t *image, int width, int height, int stride, QP_STORE_T *QP_store, int QP_stride, int chroma) {
  358. uint64_t v_local[20];
  359. uint64_t p1p2[4];
  360. int Bx, y;
  361. int QP, QPx16;
  362. uint8_t *v;
  363. int useDC, DC_on;
  364. for (y=8; y<height; y+=8) {
  365. for (Bx=0; Bx<width; Bx+=8) {
  366. QP = chroma ? QP_store[y/8*QP_stride+Bx/8]
  367.             : QP_store[y/16*QP_stride+Bx/16];
  368. QPx16 = 16 * QP;
  369. v = &(image[y*stride + Bx]) - 5*stride;
  370. useDC = deblock_vert_useDC(v, stride);
  371. if (useDC) {
  372. DC_on = deblock_vert_DC_on(v, stride, QP);
  373. if (DC_on) { 
  374. v = &(image[y*stride + Bx])- 5*stride;
  375. deblock_vert_lpf9(v_local, p1p2, v, stride, QP); 
  376. #ifdef SHOWDECISIONS_V
  377. if (!chromaFlag) {
  378. v[4*stride  ] = 
  379. v[4*stride+1] = 
  380. v[4*stride+2] = 
  381. v[4*stride+3] = 
  382. v[4*stride+4] = 
  383. v[4*stride+5] = 
  384. v[4*stride+6] = 
  385. v[4*stride+7] = 255;
  386. }  
  387. #endif
  388. }
  389. }
  390. if (!useDC) { 
  391. v = &(image[y*stride + Bx])- 5*stride;
  392. deblock_vert_default_filter(v, stride, QP);
  393. #ifdef SHOWDECISIONS_V
  394. if (!chromaFlag) {
  395. v[4*stride  ] = 
  396. v[4*stride+1] = 
  397. v[4*stride+2] = 
  398. v[4*stride+3] = 
  399. v[4*stride+4] = 
  400. v[4*stride+5] = 
  401. v[4*stride+6] = 
  402. v[4*stride+7] = 0;
  403. }  
  404. #endif
  405. }
  406. }
  407. }
  408. void dering( uint8_t *image, int width, int height, int stride, QP_STORE_T *QP_store, int QP_stride, int chroma) {
  409. int x, y, h, v, i, j;
  410. uint8_t *b8x8, *b10x10;
  411. uint8_t b8x8filtered[64];
  412. int QP, max_diff;
  413. uint8_t min, max, thr, range;
  414. uint16_t indicesP[10];  
  415. uint16_t indicesN[10];  
  416. uint16_t indices3x3[8]; 
  417. uint16_t sr;
  418. for (y=8; y<height-8; y+=8) {
  419. for (x=8; x< width-8; x+=8) {
  420. QP = chroma ? QP_store[y/8*QP_stride+x/8]
  421.             : QP_store[y/16*QP_stride+x/16];
  422. b8x8   = &(image[stride*y + x]);
  423. b10x10 = &(image[stride*(y-1) + (x-1)]);
  424. min = 255; max = 0;
  425. for (v=0; v<8; v++) {
  426. for (h=0; h<8; h++) {
  427. min = b8x8[stride*v + h] < min ? b8x8[stride*v + h] : min;
  428. max = b8x8[stride*v + h] > max ? b8x8[stride*v + h] : max;
  429. }
  430. thr = (max + min + 1) / 2;
  431. range = max - min;
  432. for (j=0; j<10; j++) {
  433. indicesP[j] = 0;
  434. for (i=0; i<10; i++) {
  435. if (b10x10[j*stride+i] >= thr) indicesP[j] |= (2 << i);
  436. }
  437. indicesN[j] = ~indicesP[j];
  438. }
  439. for (j=0; j<10; j++) {
  440. indicesP[j] = (indicesP[j]<<1) & indicesP[j] & (indicesP[j]>>1);
  441. indicesN[j] = (indicesN[j]<<1) & indicesN[j] & (indicesN[j]>>1);
  442. }
  443. for (j=1; j<9; j++) {
  444. indices3x3[j-1]  = indicesP[j-1] & indicesP[j] & indicesP[j+1];
  445. indices3x3[j-1] |= indicesN[j-1] & indicesN[j] & indicesN[j+1];
  446. }
  447. for (v=0; v<8; v++) {
  448. sr = 4;
  449. for (h=0; h<8; h++) {
  450. if (indices3x3[v] & sr) {
  451. b8x8filtered[8*v + h] = ( 8
  452.  + 1 * b10x10[stride*(v+0) + (h+0)] + 2 * b10x10[stride*(v+0) + (h+1)] + 1 * b10x10[stride*(v+0) + (h+2)]
  453.  + 2 * b10x10[stride*(v+1) + (h+0)] + 4 * b10x10[stride*(v+1) + (h+1)] + 2 * b10x10[stride*(v+1) + (h+2)]
  454.  + 1 * b10x10[stride*(v+2) + (h+0)] + 2 * b10x10[stride*(v+2) + (h+1)] + 1 * b10x10[stride*(v+2) + (h+2)]
  455. ) / 16;
  456. }
  457. sr <<= 1;
  458. }
  459. }
  460. max_diff = QP/2;
  461. for (v=0; v<8; v++) {
  462. sr = 4;
  463. for (h=0; h<8; h++) {
  464. if (indices3x3[v] & sr) {
  465. if        (b8x8filtered[8*v + h] - b8x8[stride*v + h] >  max_diff) {
  466. b8x8[stride*v + h] = b8x8[stride*v + h] + max_diff;
  467. } else if (b8x8filtered[8*v + h] - b8x8[stride*v + h] < -max_diff) {
  468. b8x8[stride*v + h] = b8x8[stride*v + h] - max_diff;
  469. } else {
  470. b8x8[stride*v + h] = b8x8filtered[8*v + h];
  471. }  
  472. }
  473. sr <<= 1;
  474. }
  475. }
  476. }
  477. }
  478. }
  479. void postprocess(unsigned char * src[], int src_stride,
  480.                  unsigned char * dst[], int dst_stride, 
  481.                  int horizontal_size,   int vertical_size, 
  482.                  QP_STORE_T *QP_store,  int QP_stride,
  483.   int mode) {
  484.   
  485. uint8_t *Y, *U, *V;
  486. int x, y;
  487. if (!(mode & PP_DONT_COPY)) {
  488. for (y=0; y<vertical_size; y++) {
  489. for (x=0; x<horizontal_size; x++) {
  490. (dst[0])[y*dst_stride + x] = (src[0])[y*src_stride + x];
  491. }
  492. }
  493. for (y=0; y<vertical_size/2; y++) {
  494. for (x=0; x<horizontal_size/2; x++) {
  495. (dst[1])[y*dst_stride/2 + x] = (src[1])[y*src_stride/2 + x];
  496. (dst[2])[y*dst_stride/2 + x] = (src[2])[y*src_stride/2 + x];
  497. }
  498. }
  499. }
  500.   
  501. Y = dst[0];
  502. U = dst[1];
  503. V = dst[2];
  504. if (mode & PP_DEBLOCK_Y_H) {
  505. deblock_horiz(Y, horizontal_size,   vertical_size,   dst_stride, QP_store, QP_stride, 0);
  506. }
  507. if (mode & PP_DEBLOCK_Y_V) {
  508. deblock_vert( Y, horizontal_size,   vertical_size,   dst_stride, QP_store, QP_stride, 0);
  509. }
  510. if (mode & PP_DEBLOCK_C_H) {
  511. deblock_horiz(U, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
  512. deblock_horiz(V, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
  513. }
  514. if (mode & PP_DEBLOCK_C_V) {
  515. deblock_vert( U, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
  516. deblock_vert( V, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
  517. }
  518. if (mode & PP_DERING_Y) {
  519. dering(       Y, horizontal_size,   vertical_size,   dst_stride, QP_store, QP_stride, 0);
  520. }
  521. if (mode & PP_DERING_C) {
  522. dering(       U, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
  523. dering(       V, horizontal_size/2, vertical_size/2, dst_stride/2, QP_store, QP_stride, 1);
  524. }
  525. }