chv_filter.cpp revision 3306cfee3bf38ab207a0504e49c2d492bb73ffbf
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/*
19------------------------------------------------------------------------------
20 INPUT AND OUTPUT DEFINITIONS
21
22 Inputs:
23    [input_variable_name] = [description of the input to module, its type
24                 definition, and length (when applicable)]
25
26 Local Stores/Buffers/Pointers Needed:
27    [local_store_name] = [description of the local store, its type
28                  definition, and length (when applicable)]
29    [local_buffer_name] = [description of the local buffer, its type
30                   definition, and length (when applicable)]
31    [local_ptr_name] = [description of the local pointer, its type
32                definition, and length (when applicable)]
33
34 Global Stores/Buffers/Pointers Needed:
35    [global_store_name] = [description of the global store, its type
36                   definition, and length (when applicable)]
37    [global_buffer_name] = [description of the global buffer, its type
38                definition, and length (when applicable)]
39    [global_ptr_name] = [description of the global pointer, its type
40                 definition, and length (when applicable)]
41
42 Outputs:
43    [return_variable_name] = [description of data/pointer returned
44                  by module, its type definition, and length
45                  (when applicable)]
46
47 Pointers and Buffers Modified:
48    [variable_bfr_ptr] points to the [describe where the
49      variable_bfr_ptr points to, its type definition, and length
50      (when applicable)]
51    [variable_bfr] contents are [describe the new contents of
52      variable_bfr]
53
54 Local Stores Modified:
55    [local_store_name] = [describe new contents, its type
56                  definition, and length (when applicable)]
57
58 Global Stores Modified:
59    [global_store_name] = [describe new contents, its type
60                   definition, and length (when applicable)]
61
62------------------------------------------------------------------------------
63 FUNCTION DESCRIPTION
64
65   For fast Deblock filtering
66   Newer version (macroblock based processing)
67
68------------------------------------------------------------------------------
69 REQUIREMENTS
70
71 [List requirements to be satisfied by this module.]
72
73------------------------------------------------------------------------------
74 REFERENCES
75
76 [List all references used in designing this module.]
77
78------------------------------------------------------------------------------
79 PSEUDO-CODE
80
81------------------------------------------------------------------------------
82 RESOURCES USED
83   When the code is written for a specific target processor the
84     the resources used should be documented below.
85
86 STACK USAGE: [stack count for this module] + [variable to represent
87          stack usage for each subroutine called]
88
89     where: [stack usage variable] = stack usage for [subroutine
90         name] (see [filename].ext)
91
92 DATA MEMORY USED: x words
93
94 PROGRAM MEMORY USED: x words
95
96 CLOCK CYCLES: [cycle count equation for this module] + [variable
97           used to represent cycle count for each subroutine
98           called]
99
100     where: [cycle count variable] = cycle count for [subroutine
101        name] (see [filename].ext)
102
103------------------------------------------------------------------------------
104*/
105
106
107/*----------------------------------------------------------------------------
108; INCLUDES
109----------------------------------------------------------------------------*/
110#include    "mp4dec_lib.h"
111#include    "post_proc.h"
112
113#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
114
115/*----------------------------------------------------------------------------
116; MACROS
117; Define module specific macros here
118----------------------------------------------------------------------------*/
119//#define FILTER_LEN_8
120
121/*----------------------------------------------------------------------------
122; DEFINES
123; Include all pre-processor statements here. Include conditional
124; compile variables also.
125----------------------------------------------------------------------------*/
126
127/*----------------------------------------------------------------------------
128; LOCAL FUNCTION DEFINITIONS
129; Function Prototype declaration
130
131----------------------------------------------------------------------------
132; LOCAL STORE/BUFFER/POINTER DEFINITIONS
133; Variable declaration - defined here and used outside this module
134----------------------------------------------------------------------------*/
135
136/*----------------------------------------------------------------------------
137; EXTERNAL FUNCTION REFERENCES
138; Declare functions defined elsewhere and referenced in this module
139----------------------------------------------------------------------------*/
140
141/*----------------------------------------------------------------------------
142; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
143; Declare variables used in this module but defined elsewhere
144----------------------------------------------------------------------------*/
145#ifdef PV_POSTPROC_ON
146
147/*************************************************************************
148    Function prototype : void CombinedHorzVertFilter(   uint8 *rec,
149                                                        int width,
150                                                        int height,
151                                                        int *QP_store,
152                                                        int chr,
153                                                        uint8 *pp_mod)
154    Parameters  :
155        rec     :   pointer to the decoded frame buffer.
156        width   :   width of decoded frame.
157        height  :   height of decoded frame
158        QP_store:   pointer to the array of QP corresponding to the decoded frame.
159                    It had only one value for each MB.
160        chr     :   luma or color indication
161                    == 0 luma
162                    == 1 color
163        pp_mod  :   The semphore used for deblocking
164
165    Remark      :   The function do the deblocking on decoded frames.
166                    First based on the semaphore info., it is divided into hard and soft filtering.
167                    To differentiate real and fake edge, it then check the difference with QP to
168                    decide whether to do the filtering or not.
169
170*************************************************************************/
171
172
173/*----------------------------------------------------------------------------
174; FUNCTION CODE
175----------------------------------------------------------------------------*/
176void CombinedHorzVertFilter(
177    uint8 *rec,
178    int width,
179    int height,
180    int16 *QP_store,
181    int chr,
182    uint8 *pp_mod)
183{
184
185    /*----------------------------------------------------------------------------
186    ; Define all local variables
187    ----------------------------------------------------------------------------*/
188    int br, bc, mbr, mbc;
189    int QP = 1;
190    uint8 *ptr, *ptr_e;
191    int pp_w, pp_h;
192    int brwidth;
193
194    int jVal0, jVal1, jVal2;
195    /*----------------------------------------------------------------------------
196    ; Function body here
197    ----------------------------------------------------------------------------*/
198    pp_w = (width >> 3);
199    pp_h = (height >> 3);
200
201    for (mbr = 0; mbr < pp_h; mbr += 2)         /* row of blocks */
202    {
203        brwidth = mbr * pp_w;               /* number of blocks above current block row */
204        for (mbc = 0; mbc < pp_w; mbc += 2)     /* col of blocks */
205        {
206            if (!chr)
207                QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
208
209            /********* for each block **************/
210            /****************** Horiz. Filtering ********************/
211            for (br = mbr + 1; br < mbr + 3; br++)  /* 2x2 blocks */
212            {
213                brwidth += pp_w;                    /* number of blocks above & left current block row */
214                /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
215                if (br < pp_h)                  /* boundary : don't do it on the lowest row block */
216                    for (bc = mbc; bc < mbc + 2; bc++)
217                    {
218                        /****** check boundary for deblocking ************/
219                        if (bc < pp_w)              /* boundary : don't do it on the most right col block */
220                        {
221                            ptr = rec + (brwidth << 6) + (bc << 3);
222                            jVal0 = brwidth + bc;
223                            if (chr)    QP = QP_store[jVal0];
224
225                            ptr_e = ptr + 8;        /* pointer to where the loop ends */
226
227                            if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
228                            {
229                                /* Horiz Hard filter */
230                                do
231                                {
232                                    jVal0 = *(ptr - width);     /* C */
233                                    jVal1 = *ptr;               /* D */
234                                    jVal2 = jVal1 - jVal0;
235
236                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
237                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
238                                    {
239                                        /* differentiate between real and fake edge */
240                                        jVal0 = ((jVal0 + jVal1) >> 1);     /* (D+C)/2 */
241                                        *(ptr - width) = (uint8)(jVal0);    /*  C */
242                                        *ptr = (uint8)(jVal0);          /*  D */
243
244                                        jVal0 = *(ptr - (width << 1));      /* B */
245                                        jVal1 = *(ptr + width);         /* E */
246                                        jVal2 = jVal1 - jVal0;      /* E-B */
247
248                                        if (jVal2 > 0)
249                                        {
250                                            jVal0 += ((jVal2 + 3) >> 2);
251                                            jVal1 -= ((jVal2 + 3) >> 2);
252                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
253                                            *(ptr + width) = (uint8)jVal1;          /* store E */
254                                        }
255                                        else if (jVal2)
256                                        {
257                                            jVal0 -= ((3 - jVal2) >> 2);
258                                            jVal1 += ((3 - jVal2) >> 2);
259                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
260                                            *(ptr + width) = (uint8)jVal1;          /* store E */
261                                        }
262
263                                        jVal0 = *(ptr - (width << 1) - width);  /* A */
264                                        jVal1 = *(ptr + (width << 1));      /* F */
265                                        jVal2 = jVal1 - jVal0;              /* (F-A) */
266
267                                        if (jVal2 > 0)
268                                        {
269                                            jVal0 += ((jVal2 + 7) >> 3);
270                                            jVal1 -= ((jVal2 + 7) >> 3);
271                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
272                                            *(ptr + (width << 1)) = (uint8)(jVal1);
273                                        }
274                                        else if (jVal2)
275                                        {
276                                            jVal0 -= ((7 - jVal2) >> 3);
277                                            jVal1 += ((7 - jVal2) >> 3);
278                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
279                                            *(ptr + (width << 1)) = (uint8)(jVal1);
280                                        }
281                                    }/* a3_0 > 2QP */
282                                }
283                                while (++ptr < ptr_e);
284                            }
285                            else   /* Horiz soft filter*/
286                            {
287                                do
288                                {
289                                    jVal0 = *(ptr - width); /* B */
290                                    jVal1 = *ptr;           /* C */
291                                    jVal2 = jVal1 - jVal0;  /* C-B */
292
293                                    if (((jVal2 > 0) && (jVal2 < (QP)))
294                                            || ((jVal2 < 0) && (jVal2 > -(QP)))) /* (C-B) compared with QP */
295                                    {
296
297                                        jVal0 = ((jVal0 + jVal1) >> 1);     /* (B+C)/2 cannot overflow; ceil() */
298                                        *(ptr - width) = (uint8)(jVal0);    /* B = (B+C)/2 */
299                                        *ptr = (uint8)jVal0;            /* C = (B+C)/2 */
300
301                                        jVal0 = *(ptr - (width << 1));      /* A */
302                                        jVal1 = *(ptr + width);         /* D */
303                                        jVal2 = jVal1 - jVal0;          /* D-A */
304
305
306                                        if (jVal2 > 0)
307                                        {
308                                            jVal1 -= ((jVal2 + 7) >> 3);
309                                            jVal0 += ((jVal2 + 7) >> 3);
310                                            *(ptr - (width << 1)) = (uint8)jVal0;       /* A */
311                                            *(ptr + width) = (uint8)jVal1;          /* D */
312                                        }
313                                        else if (jVal2)
314                                        {
315                                            jVal1 += ((7 - jVal2) >> 3);
316                                            jVal0 -= ((7 - jVal2) >> 3);
317                                            *(ptr - (width << 1)) = (uint8)jVal0;       /* A */
318                                            *(ptr + width) = (uint8)jVal1;          /* D */
319                                        }
320                                    }
321                                }
322                                while (++ptr < ptr_e);
323                            } /* Soft filter*/
324                        }/* boundary checking*/
325                    }/*bc*/
326            }/*br*/
327            brwidth -= (pp_w << 1);
328            /****************** Vert. Filtering ********************/
329            for (br = mbr; br < mbr + 2; br++)
330            {
331                if (br < pp_h)
332                    for (bc = mbc + 1; bc < mbc + 3; bc++)
333                    {
334                        /****** check boundary for deblocking ************/
335                        if (bc < pp_w)
336                        {
337                            ptr = rec + (brwidth << 6) + (bc << 3);
338                            jVal0 = brwidth + bc;
339                            if (chr)    QP = QP_store[jVal0];
340
341                            ptr_e = ptr + (width << 3);
342
343                            if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
344                            {
345                                /* Vert Hard filter */
346                                do
347                                {
348                                    jVal1 = *ptr;       /* D */
349                                    jVal0 = *(ptr - 1); /* C */
350                                    jVal2 = jVal1 - jVal0;  /* D-C */
351
352                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
353                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
354                                    {
355                                        jVal1 = (jVal0 + jVal1) >> 1;   /* (C+D)/2 */
356                                        *ptr        =   jVal1;
357                                        *(ptr - 1)  =   jVal1;
358
359                                        jVal1 = *(ptr + 1);     /* E */
360                                        jVal0 = *(ptr - 2);     /* B */
361                                        jVal2 = jVal1 - jVal0;      /* E-B */
362
363                                        if (jVal2 > 0)
364                                        {
365                                            jVal1 -= ((jVal2 + 3) >> 2);        /* E = E -(E-B)/4 */
366                                            jVal0 += ((jVal2 + 3) >> 2);        /* B = B +(E-B)/4 */
367                                            *(ptr + 1) = jVal1;
368                                            *(ptr - 2) = jVal0;
369                                        }
370                                        else if (jVal2)
371                                        {
372                                            jVal1 += ((3 - jVal2) >> 2);        /* E = E -(E-B)/4 */
373                                            jVal0 -= ((3 - jVal2) >> 2);        /* B = B +(E-B)/4 */
374                                            *(ptr + 1) = jVal1;
375                                            *(ptr - 2) = jVal0;
376                                        }
377
378                                        jVal1 = *(ptr + 2);     /* F */
379                                        jVal0 = *(ptr - 3);     /* A */
380
381                                        jVal2 = jVal1 - jVal0;          /* (F-A) */
382
383                                        if (jVal2 > 0)
384                                        {
385                                            jVal1 -= ((jVal2 + 7) >> 3);    /* F -= (F-A)/8 */
386                                            jVal0 += ((jVal2 + 7) >> 3);    /* A += (F-A)/8 */
387                                            *(ptr + 2) = jVal1;
388                                            *(ptr - 3) = jVal0;
389                                        }
390                                        else if (jVal2)
391                                        {
392                                            jVal1 -= ((jVal2 - 7) >> 3);    /* F -= (F-A)/8 */
393                                            jVal0 += ((jVal2 - 7) >> 3);    /* A += (F-A)/8 */
394                                            *(ptr + 2) = jVal1;
395                                            *(ptr - 3) = jVal0;
396                                        }
397                                    }   /* end of ver hard filetering */
398                                }
399                                while ((ptr += width) < ptr_e);
400                            }
401                            else   /* Vert soft filter*/
402                            {
403                                do
404                                {
405                                    jVal1 = *ptr;               /* C */
406                                    jVal0 = *(ptr - 1);         /* B */
407                                    jVal2 = jVal1 - jVal0;
408
409                                    if (((jVal2 > 0) && (jVal2 < (QP)))
410                                            || ((jVal2 < 0) && (jVal2 > -(QP))))
411                                    {
412
413                                        jVal1 = (jVal0 + jVal1 + 1) >> 1;
414                                        *ptr = jVal1;           /* C */
415                                        *(ptr - 1) = jVal1;     /* B */
416
417                                        jVal1 = *(ptr + 1);     /* D */
418                                        jVal0 = *(ptr - 2);     /* A */
419                                        jVal2 = (jVal1 - jVal0);        /* D- A */
420
421                                        if (jVal2 > 0)
422                                        {
423                                            jVal1 -= (((jVal2) + 7) >> 3);      /* D -= (D-A)/8 */
424                                            jVal0 += (((jVal2) + 7) >> 3);      /* A += (D-A)/8 */
425                                            *(ptr + 1) = jVal1;
426                                            *(ptr - 2) = jVal0;
427
428                                        }
429                                        else if (jVal2)
430                                        {
431                                            jVal1 += ((7 - (jVal2)) >> 3);      /* D -= (D-A)/8 */
432                                            jVal0 -= ((7 - (jVal2)) >> 3);      /* A += (D-A)/8 */
433                                            *(ptr + 1) = jVal1;
434                                            *(ptr - 2) = jVal0;
435                                        }
436                                    }
437                                }
438                                while ((ptr += width) < ptr_e);
439                            } /* Soft filter*/
440                        } /* boundary*/
441                    } /*bc*/
442                brwidth += pp_w;
443            }/*br*/
444            brwidth -= (pp_w << 1);
445        }/*mbc*/
446        brwidth += (pp_w << 1);
447    }/*mbr*/
448    /*----------------------------------------------------------------------------
449    ; Return nothing or data or data pointer
450    ----------------------------------------------------------------------------*/
451    return;
452}
453void CombinedHorzVertFilter_NoSoftDeblocking(
454    uint8 *rec,
455    int width,
456    int height,
457    int16 *QP_store,
458    int chr,
459    uint8 *pp_mod)
460{
461
462    /*----------------------------------------------------------------------------
463    ; Define all local variables
464    ----------------------------------------------------------------------------*/
465    int br, bc, mbr, mbc;
466    int QP = 1;
467    uint8 *ptr, *ptr_e;
468    int pp_w, pp_h;
469    int brwidth;
470
471    int jVal0, jVal1, jVal2;
472    /*----------------------------------------------------------------------------
473    ; Function body here
474    ----------------------------------------------------------------------------*/
475    pp_w = (width >> 3);
476    pp_h = (height >> 3);
477
478    for (mbr = 0; mbr < pp_h; mbr += 2)         /* row of blocks */
479    {
480        brwidth = mbr * pp_w;               /* number of blocks above current block row */
481        for (mbc = 0; mbc < pp_w; mbc += 2)     /* col of blocks */
482        {
483            if (!chr)
484                QP = QP_store[(brwidth>>2) + (mbc>>1)]; /* QP is per MB based value */
485
486            /********* for each block **************/
487            /****************** Horiz. Filtering ********************/
488            for (br = mbr + 1; br < mbr + 3; br++)  /* 2x2 blocks */
489            {
490                brwidth += pp_w;                    /* number of blocks above & left current block row */
491                /* the profile on ARM920T shows separate these two boundary check is faster than combine them */
492                if (br < pp_h)                  /* boundary : don't do it on the lowest row block */
493                    for (bc = mbc; bc < mbc + 2; bc++)
494                    {
495                        /****** check boundary for deblocking ************/
496                        if (bc < pp_w)              /* boundary : don't do it on the most right col block */
497                        {
498                            ptr = rec + (brwidth << 6) + (bc << 3);
499                            jVal0 = brwidth + bc;
500                            if (chr)    QP = QP_store[jVal0];
501
502                            ptr_e = ptr + 8;        /* pointer to where the loop ends */
503
504                            if (((pp_mod[jVal0]&0x02)) && ((pp_mod[jVal0-pp_w]&0x02)))
505                            {
506                                /* Horiz Hard filter */
507                                do
508                                {
509                                    jVal0 = *(ptr - width);     /* C */
510                                    jVal1 = *ptr;               /* D */
511                                    jVal2 = jVal1 - jVal0;
512
513                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
514                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1)))) /* (D-C) compared with 2QP */
515                                    {
516                                        /* differentiate between real and fake edge */
517                                        jVal0 = ((jVal0 + jVal1) >> 1);     /* (D+C)/2 */
518                                        *(ptr - width) = (uint8)(jVal0);    /*  C */
519                                        *ptr = (uint8)(jVal0);          /*  D */
520
521                                        jVal0 = *(ptr - (width << 1));      /* B */
522                                        jVal1 = *(ptr + width);         /* E */
523                                        jVal2 = jVal1 - jVal0;      /* E-B */
524
525                                        if (jVal2 > 0)
526                                        {
527                                            jVal0 += ((jVal2 + 3) >> 2);
528                                            jVal1 -= ((jVal2 + 3) >> 2);
529                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
530                                            *(ptr + width) = (uint8)jVal1;          /* store E */
531                                        }
532                                        else if (jVal2)
533                                        {
534                                            jVal0 -= ((3 - jVal2) >> 2);
535                                            jVal1 += ((3 - jVal2) >> 2);
536                                            *(ptr - (width << 1)) = (uint8)jVal0;       /*  store B */
537                                            *(ptr + width) = (uint8)jVal1;          /* store E */
538                                        }
539
540                                        jVal0 = *(ptr - (width << 1) - width);  /* A */
541                                        jVal1 = *(ptr + (width << 1));      /* F */
542                                        jVal2 = jVal1 - jVal0;              /* (F-A) */
543
544                                        if (jVal2 > 0)
545                                        {
546                                            jVal0 += ((jVal2 + 7) >> 3);
547                                            jVal1 -= ((jVal2 + 7) >> 3);
548                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
549                                            *(ptr + (width << 1)) = (uint8)(jVal1);
550                                        }
551                                        else if (jVal2)
552                                        {
553                                            jVal0 -= ((7 - jVal2) >> 3);
554                                            jVal1 += ((7 - jVal2) >> 3);
555                                            *(ptr - (width << 1) - width) = (uint8)(jVal0);
556                                            *(ptr + (width << 1)) = (uint8)(jVal1);
557                                        }
558                                    }/* a3_0 > 2QP */
559                                }
560                                while (++ptr < ptr_e);
561                            }
562
563                        }/* boundary checking*/
564                    }/*bc*/
565            }/*br*/
566            brwidth -= (pp_w << 1);
567            /****************** Vert. Filtering ********************/
568            for (br = mbr; br < mbr + 2; br++)
569            {
570                if (br < pp_h)
571                    for (bc = mbc + 1; bc < mbc + 3; bc++)
572                    {
573                        /****** check boundary for deblocking ************/
574                        if (bc < pp_w)
575                        {
576                            ptr = rec + (brwidth << 6) + (bc << 3);
577                            jVal0 = brwidth + bc;
578                            if (chr)    QP = QP_store[jVal0];
579
580                            ptr_e = ptr + (width << 3);
581
582                            if (((pp_mod[jVal0-1]&0x01)) && ((pp_mod[jVal0]&0x01)))
583                            {
584                                /* Vert Hard filter */
585                                do
586                                {
587                                    jVal1 = *ptr;       /* D */
588                                    jVal0 = *(ptr - 1); /* C */
589                                    jVal2 = jVal1 - jVal0;  /* D-C */
590
591                                    if (((jVal2 > 0) && (jVal2 < (QP << 1)))
592                                            || ((jVal2 < 0) && (jVal2 > -(QP << 1))))
593                                    {
594                                        jVal1 = (jVal0 + jVal1) >> 1;   /* (C+D)/2 */
595                                        *ptr        =   jVal1;
596                                        *(ptr - 1)  =   jVal1;
597
598                                        jVal1 = *(ptr + 1);     /* E */
599                                        jVal0 = *(ptr - 2);     /* B */
600                                        jVal2 = jVal1 - jVal0;      /* E-B */
601
602                                        if (jVal2 > 0)
603                                        {
604                                            jVal1 -= ((jVal2 + 3) >> 2);        /* E = E -(E-B)/4 */
605                                            jVal0 += ((jVal2 + 3) >> 2);        /* B = B +(E-B)/4 */
606                                            *(ptr + 1) = jVal1;
607                                            *(ptr - 2) = jVal0;
608                                        }
609                                        else if (jVal2)
610                                        {
611                                            jVal1 += ((3 - jVal2) >> 2);        /* E = E -(E-B)/4 */
612                                            jVal0 -= ((3 - jVal2) >> 2);        /* B = B +(E-B)/4 */
613                                            *(ptr + 1) = jVal1;
614                                            *(ptr - 2) = jVal0;
615                                        }
616
617                                        jVal1 = *(ptr + 2);     /* F */
618                                        jVal0 = *(ptr - 3);     /* A */
619
620                                        jVal2 = jVal1 - jVal0;          /* (F-A) */
621
622                                        if (jVal2 > 0)
623                                        {
624                                            jVal1 -= ((jVal2 + 7) >> 3);    /* F -= (F-A)/8 */
625                                            jVal0 += ((jVal2 + 7) >> 3);    /* A += (F-A)/8 */
626                                            *(ptr + 2) = jVal1;
627                                            *(ptr - 3) = jVal0;
628                                        }
629                                        else if (jVal2)
630                                        {
631                                            jVal1 -= ((jVal2 - 7) >> 3);    /* F -= (F-A)/8 */
632                                            jVal0 += ((jVal2 - 7) >> 3);    /* A += (F-A)/8 */
633                                            *(ptr + 2) = jVal1;
634                                            *(ptr - 3) = jVal0;
635                                        }
636                                    }   /* end of ver hard filetering */
637                                }
638                                while ((ptr += width) < ptr_e);
639                            }
640
641                        } /* boundary*/
642                    } /*bc*/
643                brwidth += pp_w;
644            }/*br*/
645            brwidth -= (pp_w << 1);
646        }/*mbc*/
647        brwidth += (pp_w << 1);
648    }/*mbr*/
649    /*----------------------------------------------------------------------------
650    ; Return nothing or data or data pointer
651    ----------------------------------------------------------------------------*/
652    return;
653}
654#endif
655