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 ----------------------------------------------------------------------------*/
CombinedHorzVertFilter(uint8 * rec,int width,int height,int16 * QP_store,int chr,uint8 * pp_mod)176 void 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 }
CombinedHorzVertFilter_NoSoftDeblocking(uint8 * rec,int width,int height,int16 * QP_store,int chr,uint8 * pp_mod)453 void 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