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
23void 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