1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include    "mp4dec_lib.h"
19 #include    "post_proc.h"
20 
21 #ifdef PV_POSTPROC_ON
22 
Deringing_Chroma(uint8 * Rec_C,int width,int height,int16 * QP_store,int,uint8 * pp_mod)23 void Deringing_Chroma(
24     uint8 *Rec_C,
25     int width,
26     int height,
27     int16 *QP_store,
28     int,
29     uint8 *pp_mod
30 )
31 {
32     /*----------------------------------------------------------------------------
33     ; Define all local variables
34     ----------------------------------------------------------------------------*/
35     int thres;
36     int v_blk, h_blk;
37     int max_diff;
38     int v_pel, h_pel;
39     int max_blk, min_blk;
40     int v0, h0;
41     uint8 *ptr;
42     int sum, sum1, incr;
43     int32 addr_v;
44     int sign_v[10], sum_v[10];
45     int *ptr2, *ptr3;
46     uint8 pelu, pelc, pell;
47     incr = width - BLKSIZE;
48 
49     /*----------------------------------------------------------------------------
50     ; Function body here
51     ----------------------------------------------------------------------------*/
52     /* chrominance */
53     /* Do the first line (7 pixels at a time => Don't use MMX)*/
54     for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
55     {
56         max_diff = (QP_store[h_blk>>3] >> 2) + 4;
57         ptr = &Rec_C[h_blk];
58         max_blk = min_blk = *ptr;
59         FindMaxMin(ptr, &min_blk, &max_blk, width);
60         h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
61 
62         if (max_blk - min_blk >= 4)
63         {
64             thres = (max_blk + min_blk + 1) >> 1;
65 
66 
67             for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
68             {
69                 addr_v = (int32)v_pel * width;
70                 ptr = &Rec_C[addr_v + h0 - 1];
71                 ptr2 = &sum_v[0];
72                 ptr3 = &sign_v[0];
73 
74                 pelu = *(ptr - width);
75                 pelc = *ptr;
76                 pell = *(ptr + width);
77                 ptr++;
78                 *ptr2++ = pelu + (pelc << 1) + pell;
79                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
80 
81                 pelu = *(ptr - width);
82                 pelc = *ptr;
83                 pell = *(ptr + width);
84                 ptr++;
85                 *ptr2++ = pelu + (pelc << 1) + pell;
86                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
87 
88                 for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
89                 {
90                     pelu = *(ptr - width);
91                     pelc = *ptr;
92                     pell = *(ptr + width);
93 
94                     *ptr2 = pelu + (pelc << 1) + pell;
95                     *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
96 
97                     sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
98                     if (sum1 == 0 || sum1 == 9)
99                     {
100                         sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
101 
102                         ptr--;
103                         if (PV_ABS(*ptr - sum) > max_diff)
104                         {
105                             if (sum > *ptr)
106                                 sum = *ptr + max_diff;
107                             else
108                                 sum = *ptr - max_diff;
109                         }
110                         *ptr++ = (uint8) sum;
111                     }
112                     ptr++;
113                     ptr2++;
114                     ptr3++;
115                 }
116             }
117         }
118     }
119 
120     for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
121     {
122         v0 = v_blk - 1;
123         /* Do the first block (pixels=7 => No MMX) */
124         max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
125         ptr = &Rec_C[(int32)v_blk * width];
126         max_blk = min_blk = *ptr;
127         FindMaxMin(ptr, &min_blk, &max_blk, incr);
128 
129         if (max_blk - min_blk >= 4)
130         {
131             thres = (max_blk + min_blk + 1) >> 1;
132 
133             for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
134             {
135                 addr_v = v_pel * width;
136                 ptr = &Rec_C[addr_v];
137                 ptr2 = &sum_v[0];
138                 ptr3 = &sign_v[0];
139 
140                 pelu = *(ptr - width);
141                 pelc = *ptr;
142                 pell = *(ptr + width);
143                 ptr++;
144                 *ptr2++ = pelu + (pelc << 1) + pell;
145                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
146 
147                 pelu = *(ptr - width);
148                 pelc = *ptr;
149                 pell = *(ptr + width);
150                 ptr++;
151                 *ptr2++ = pelu + (pelc << 1) + pell;
152                 *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
153 
154                 for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
155                 {
156                     pelu = *(ptr - width);
157                     pelc = *ptr;
158                     pell = *(ptr + width);
159 
160                     *ptr2 = pelu + (pelc << 1) + pell;
161                     *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
162 
163                     sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
164                     if (sum1 == 0 || sum1 == 9)
165                     {
166                         sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
167 
168                         ptr--;
169                         if (PV_ABS(*ptr - sum) > max_diff)
170                         {
171                             if (sum > *ptr)
172                                 sum = *ptr + max_diff;
173                             else
174                                 sum = *ptr - max_diff;
175                         }
176                         *ptr++ = (uint8) sum;
177                     }
178                     ptr++;
179                     ptr2++;
180                     ptr3++;
181                 }
182             }
183         }
184 
185 
186         /* Do the rest in MMX */
187         for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
188         {
189             if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
190             {
191                 max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
192                 ptr = &Rec_C[(int32)v_blk * width + h_blk];
193                 max_blk = min_blk = *ptr;
194                 FindMaxMin(ptr, &min_blk, &max_blk, incr);
195                 h0 = h_blk - 1;
196 
197                 if (max_blk - min_blk >= 4)
198                 {
199                     thres = (max_blk + min_blk + 1) >> 1;
200 #ifdef NoMMX
201                     AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
202 #else
203                     DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
204 #endif
205                 }
206             }
207         }
208     } /* macroblock level */
209 
210     /*----------------------------------------------------------------------------
211     ; Return nothing or data or data pointer
212     ----------------------------------------------------------------------------*/
213     return;
214 }
215 #endif
216