• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "avclib_common.h"
19 #include "oscl_mem.h"
20 
21 #define MAX_QP 51
22 #define MB_BLOCK_SIZE 16
23 
24 // NOTE: these 3 tables are for funtion GetStrength() only
25 const static int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303};
26 
27 
28 // NOTE: these 3 tables are for funtion EdgeLoop() only
29 // NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values
30 
31 const static int ALPHA_TABLE[52]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,  7, 8, 9, 10, 12, 13, 15, 17,  20, 22, 25, 28, 32, 36, 40, 45,  50, 56, 63, 71, 80, 90, 101, 113,  127, 144, 162, 182, 203, 226, 255, 255} ;
32 const static int BETA_TABLE[52]   = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,  3, 3, 3, 4, 4, 4, 6, 6,   7, 7, 8, 8, 9, 9, 10, 10,  11, 11, 12, 12, 13, 13, 14, 14,   15, 15, 16, 16, 17, 17, 18, 18} ;
33 const static int CLIP_TAB[52][5]  =
34 {
35     { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0},
36     { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0},
37     { 0, 0, 0, 0, 0}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 1, 1, 1, 1},
38     { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 2, 3, 3},
39     { 0, 1, 2, 3, 3}, { 0, 2, 2, 3, 3}, { 0, 2, 2, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 3, 3, 5, 5}, { 0, 3, 4, 6, 6}, { 0, 3, 4, 6, 6},
40     { 0, 4, 5, 7, 7}, { 0, 4, 5, 8, 8}, { 0, 4, 6, 9, 9}, { 0, 5, 7, 10, 10}, { 0, 6, 8, 11, 11}, { 0, 6, 8, 13, 13}, { 0, 7, 10, 14, 14}, { 0, 8, 11, 16, 16},
41     { 0, 9, 12, 18, 18}, { 0, 10, 13, 20, 20}, { 0, 11, 15, 23, 23}, { 0, 13, 17, 25, 25}
42 };
43 
44 // NOTE: this table is only QP clipping, index = QP + video->FilterOffsetA/B, clipped to [0, 51]
45 //       video->FilterOffsetA/B is in {-12, 12]
46 const static int QP_CLIP_TAB[76] =
47 {
48     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,              // [-12, 0]
49     1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
50     13, 14, 15, 16, 17, 18, 19, 20, 21,
51     22, 23, 24, 25, 26, 27, 28, 29, 30,
52     31, 32, 33, 34, 35, 36, 37, 38, 39,
53     40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // [1, 51]
54     51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51      // [52,63]
55 };
56 
57 static void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV);
58 //static void GetStrength(AVCCommonObj *video, uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir, int edge);
59 static void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir);
60 static void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ);
61 static void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ);
62 static void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
63 static void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
64 static void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
65 static void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
66 
67 /*
68  *****************************************************************************************
69  * \brief Filter all macroblocks in order of increasing macroblock address.
70  *****************************************************************************************
71 */
72 
DeblockPicture(AVCCommonObj * video)73 OSCL_EXPORT_REF AVCStatus DeblockPicture(AVCCommonObj *video)
74 {
75     uint   i, j;
76     int   pitch = video->currPic->pitch, pitch_c, width;
77     uint8 *SrcY, *SrcU, *SrcV;
78 
79     SrcY = video->currPic->Sl;      // pointers to source
80     SrcU = video->currPic->Scb;
81     SrcV = video->currPic->Scr;
82     pitch_c = pitch >> 1;
83     width = video->currPic->width;
84 
85     for (i = 0; i < video->PicHeightInMbs; i++)
86     {
87         for (j = 0; j < video->PicWidthInMbs; j++)
88         {
89             DeblockMb(video, j, i, SrcY, SrcU, SrcV);
90             // update SrcY, SrcU, SrcV
91             SrcY += MB_BLOCK_SIZE;
92             SrcU += (MB_BLOCK_SIZE >> 1);
93             SrcV += (MB_BLOCK_SIZE >> 1);
94         }
95 
96         SrcY += ((pitch << 4) - width);
97         SrcU += ((pitch_c << 3) - (width >> 1));
98         SrcV += ((pitch_c << 3) - (width >> 1));
99     }
100 
101     return AVC_SUCCESS;
102 }
103 
104 #ifdef MB_BASED_DEBLOCK
105 /*
106  *****************************************************************************************
107  * \brief Filter one macroblocks in a fast macroblock memory and copy it to frame
108  *****************************************************************************************
109 */
MBInLoopDeblock(AVCCommonObj * video)110 void MBInLoopDeblock(AVCCommonObj *video)
111 {
112     AVCPictureData *currPic = video->currPic;
113 #ifdef USE_PRED_BLOCK
114     uint8 *predCb, *predCr, *pred_block;
115     int i, j, dst_width, dst_height, dst_widthc, dst_heightc;
116 #endif
117     int pitch = currPic->pitch;
118     int x_pos = video->mb_x;
119     int y_pos = video->mb_y;
120     uint8 *curL, *curCb, *curCr;
121     int offset;
122 
123     offset = (y_pos << 4) * pitch;
124 
125     curL = currPic->Sl + offset + (x_pos << 4);
126 
127     offset >>= 2;
128     offset += (x_pos << 3);
129 
130     curCb = currPic->Scb + offset;
131     curCr = currPic->Scr + offset;
132 
133 #ifdef USE_PRED_BLOCK
134     pred_block = video->pred;
135 
136     /* 1. copy neighboring pixels from frame to the video->pred_block */
137     if (y_pos) /* not the 0th row */
138     {
139         /* copy to the top 4 lines of the macroblock */
140         curL -= (pitch << 2); /* go back 4 lines */
141 
142         oscl_memcpy(pred_block + 4, curL, 16);
143         curL += pitch;
144         oscl_memcpy(pred_block + 24, curL, 16);
145         curL += pitch;
146         oscl_memcpy(pred_block + 44, curL, 16);
147         curL += pitch;
148         oscl_memcpy(pred_block + 64, curL, 16);
149         curL += pitch;
150 
151         curCb -= (pitch << 1); /* go back 4 lines chroma */
152         curCr -= (pitch << 1);
153 
154         pred_block += 400;
155 
156         oscl_memcpy(pred_block + 4, curCb, 8);
157         curCb += (pitch >> 1);
158         oscl_memcpy(pred_block + 16, curCb, 8);
159         curCb += (pitch >> 1);
160         oscl_memcpy(pred_block + 28, curCb, 8);
161         curCb += (pitch >> 1);
162         oscl_memcpy(pred_block + 40, curCb, 8);
163         curCb += (pitch >> 1);
164 
165         pred_block += 144;
166         oscl_memcpy(pred_block + 4, curCr, 8);
167         curCr += (pitch >> 1);
168         oscl_memcpy(pred_block + 16, curCr, 8);
169         curCr += (pitch >> 1);
170         oscl_memcpy(pred_block + 28, curCr, 8);
171         curCr += (pitch >> 1);
172         oscl_memcpy(pred_block + 40, curCr, 8);
173         curCr += (pitch >> 1);
174 
175         pred_block = video->pred;
176     }
177 
178     /* 2. perform deblocking. */
179     DeblockMb(video, x_pos, y_pos, pred_block + 84, pred_block + 452, pred_block + 596);
180 
181     /* 3. copy it back to the frame and update pred_block */
182     predCb = pred_block + 400;
183     predCr = predCb + 144;
184 
185     /* find the range of the block inside pred_block to be copied back */
186     if (y_pos)  /* the first row */
187     {
188         curL -= (pitch << 2);
189         curCb -= (pitch << 1);
190         curCr -= (pitch << 1);
191 
192         dst_height = 20;
193         dst_heightc = 12;
194     }
195     else
196     {
197         pred_block += 80;
198         predCb += 48;
199         predCr += 48;
200         dst_height = 16;
201         dst_heightc = 8;
202     }
203 
204     if (x_pos) /* find the width */
205     {
206         curL -= 4;
207         curCb -= 4;
208         curCr -= 4;
209         if (x_pos == (int)(video->PicWidthInMbs - 1))
210         {
211             dst_width = 20;
212             dst_widthc = 12;
213         }
214         else
215         {
216             dst_width = 16;
217             dst_widthc = 8;
218         }
219     }
220     else
221     {
222         pred_block += 4;
223         predCb += 4;
224         predCr += 4;
225         dst_width = 12;
226         dst_widthc = 4;
227     }
228 
229     /* perform copy */
230     for (j = 0; j < dst_height; j++)
231     {
232         oscl_memcpy(curL, pred_block, dst_width);
233         curL += pitch;
234         pred_block += 20;
235     }
236     for (j = 0; j < dst_heightc; j++)
237     {
238         oscl_memcpy(curCb, predCb, dst_widthc);
239         oscl_memcpy(curCr, predCr, dst_widthc);
240         curCb += (pitch >> 1);
241         curCr += (pitch >> 1);
242         predCb += 12;
243         predCr += 12;
244     }
245 
246     if (x_pos != (int)(video->PicWidthInMbs - 1)) /* now copy from the right-most 4 columns to the left-most 4 columns */
247     {
248         pred_block = video->pred;
249         for (i = 0; i < 20; i += 4)
250         {
251             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
252             pred_block += 20;
253             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
254             pred_block += 20;
255             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
256             pred_block += 20;
257             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
258             pred_block += 20;
259         }
260 
261         for (i = 0; i < 24; i += 4)
262         {
263             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
264             pred_block += 12;
265             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
266             pred_block += 12;
267             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
268             pred_block += 12;
269             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
270             pred_block += 12;
271         }
272 
273     }
274 #else
275     DeblockMb(video, x_pos, y_pos, curL, curCb, curCr);
276 #endif
277 
278     return ;
279 }
280 #endif
281 
282 /*
283  *****************************************************************************************
284  * \brief Deblocking filter for one macroblock.
285  *****************************************************************************************
286  */
287 
DeblockMb(AVCCommonObj * video,int mb_x,int mb_y,uint8 * SrcY,uint8 * SrcU,uint8 * SrcV)288 void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV)
289 {
290     AVCMacroblock *MbP, *MbQ;
291     int     edge, QP, QPC;
292     int     filterLeftMbEdgeFlag = (mb_x != 0);
293     int     filterTopMbEdgeFlag  = (mb_y != 0);
294     int     pitch = video->currPic->pitch;
295     int     indexA, indexB, tmp;
296     int     Alpha, Beta, Alpha_c, Beta_c;
297     int     mbNum = mb_y * video->PicWidthInMbs + mb_x;
298     int     *clipTable, *clipTable_c, *qp_clip_tab;
299     uint8   Strength[16];
300     void*     str;
301 
302     MbQ = &(video->mblock[mbNum]);      // current Mb
303 
304 
305     // If filter is disabled, return
306     if (video->sliceHdr->disable_deblocking_filter_idc == 1) return;
307 
308     if (video->sliceHdr->disable_deblocking_filter_idc == 2)
309     {
310         // don't filter at slice boundaries
311         filterLeftMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - 1, mbNum);
312         filterTopMbEdgeFlag  = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - video->PicWidthInMbs, mbNum);
313     }
314 
315     /* NOTE: edge=0 and edge=1~3 are separate cases because of the difference of MbP, index A and indexB calculation */
316     /*       for edge = 1~3, MbP, indexA and indexB remain the same, and thus there is no need to re-calculate them for each edge */
317 
318     qp_clip_tab = (int *)QP_CLIP_TAB + 12;
319 
320     /* 1.VERTICAL EDGE + MB BOUNDARY (edge = 0) */
321     if (filterLeftMbEdgeFlag)
322     {
323         MbP = MbQ - 1;
324         //GetStrength(video, Strength, MbP, MbQ, 0, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
325         GetStrength_Edge0(Strength, MbP, MbQ, 0);
326 
327         str = (void*)Strength; //de-ref type-punned pointer fix
328         if (*((uint32*)str))    // only if one of the 4 Strength bytes is != 0
329         {
330             QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
331             indexA = QP + video->FilterOffsetA;
332             indexB = QP + video->FilterOffsetB;
333             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
334             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
335 
336             Alpha  = ALPHA_TABLE[indexA];
337             Beta = BETA_TABLE[indexB];
338             clipTable = (int *) CLIP_TAB[indexA];
339 
340             if (Alpha > 0 && Beta > 0)
341 #ifdef USE_PRED_BLOCK
342                 EdgeLoop_Luma_vertical(SrcY, Strength,  Alpha, Beta, clipTable, 20);
343 #else
344                 EdgeLoop_Luma_vertical(SrcY, Strength,  Alpha, Beta, clipTable, pitch);
345 #endif
346 
347             QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
348             indexA = QPC + video->FilterOffsetA;
349             indexB = QPC + video->FilterOffsetB;
350             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
351             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
352 
353             Alpha  = ALPHA_TABLE[indexA];
354             Beta = BETA_TABLE[indexB];
355             clipTable = (int *) CLIP_TAB[indexA];
356             if (Alpha > 0 && Beta > 0)
357             {
358 #ifdef USE_PRED_BLOCK
359                 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, 12);
360                 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, 12);
361 #else
362                 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
363                 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
364 #endif
365             }
366         }
367 
368     } /* end of: if(filterLeftMbEdgeFlag) */
369 
370     /* 2.VERTICAL EDGE (no boundary), the edges are all inside a MB */
371     /* First calculate the necesary parameters all at once, outside the loop */
372     MbP = MbQ;
373 
374     indexA = MbQ->QPy + video->FilterOffsetA;
375     indexB = MbQ->QPy + video->FilterOffsetB;
376     //  index
377     indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
378     indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
379 
380     Alpha = ALPHA_TABLE[indexA];
381     Beta = BETA_TABLE[indexB];
382     clipTable = (int *)CLIP_TAB[indexA];
383 
384     /* Save Alpha,  Beta and clipTable for future use, with the obselete variables filterLeftMbEdgeFlag, mbNum amd tmp */
385     filterLeftMbEdgeFlag = Alpha;
386     mbNum = Beta;
387     tmp = (int)clipTable;
388 
389     indexA = MbQ->QPc + video->FilterOffsetA;
390     indexB = MbQ->QPc + video->FilterOffsetB;
391     indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
392     indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
393 
394     Alpha_c  = ALPHA_TABLE[indexA];
395     Beta_c = BETA_TABLE[indexB];
396     clipTable_c = (int *)CLIP_TAB[indexA];
397 
398     GetStrength_VerticalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
399 
400     for (edge = 1; edge < 4; edge++)  // 4 vertical strips of 16 pel
401     {
402         //GetStrength_VerticalEdges(video, Strength, MbP, MbQ, 0, edge); // Strength for 4 blks in 1 stripe, 0 => vertical edge
403         if (*((int*)(Strength + (edge << 2))))   // only if one of the 4 Strength bytes is != 0
404         {
405             if (Alpha > 0 && Beta > 0)
406 #ifdef USE_PRED_BLOCK
407                 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2),  Alpha, Beta, clipTable, 20);
408 #else
409                 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2),  Alpha, Beta, clipTable, pitch);
410 #endif
411 
412             if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
413             {
414 #ifdef USE_PRED_BLOCK
415                 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
416                 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
417 #else
418                 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
419                 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
420 #endif
421             }
422         }
423 
424     } //end edge
425 
426 
427 
428     /* 3.HORIZONTAL EDGE + MB BOUNDARY (edge = 0) */
429     if (filterTopMbEdgeFlag)
430     {
431         MbP = MbQ - video->PicWidthInMbs;
432         //GetStrength(video, Strength, MbP, MbQ, 1, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
433         GetStrength_Edge0(Strength, MbP, MbQ, 1);
434         str = (void*)Strength; //de-ref type-punned pointer fix
435         if (*((uint32*)str))    // only if one of the 4 Strength bytes is != 0
436         {
437             QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
438             indexA = QP + video->FilterOffsetA;
439             indexB = QP + video->FilterOffsetB;
440             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
441             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
442 
443             Alpha  = ALPHA_TABLE[indexA];
444             Beta = BETA_TABLE[indexB];
445             clipTable = (int *)CLIP_TAB[indexA];
446 
447             if (Alpha > 0 && Beta > 0)
448             {
449 #ifdef USE_PRED_BLOCK
450                 EdgeLoop_Luma_horizontal(SrcY, Strength,  Alpha, Beta, clipTable, 20);
451 #else
452                 EdgeLoop_Luma_horizontal(SrcY, Strength,  Alpha, Beta, clipTable, pitch);
453 #endif
454             }
455 
456             QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
457             indexA = QPC + video->FilterOffsetA;
458             indexB = QPC + video->FilterOffsetB;
459             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
460             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
461 
462             Alpha  = ALPHA_TABLE[indexA];
463             Beta = BETA_TABLE[indexB];
464             clipTable = (int *)CLIP_TAB[indexA];
465             if (Alpha > 0 && Beta > 0)
466             {
467 #ifdef USE_PRED_BLOCK
468                 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, 12);
469                 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, 12);
470 #else
471                 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
472                 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
473 #endif
474             }
475         }
476 
477     } /* end of: if(filterTopMbEdgeFlag) */
478 
479 
480     /* 4.HORIZONTAL EDGE (no boundary), the edges are inside a MB */
481     MbP = MbQ;
482 
483     /* Recover Alpha,  Beta and clipTable for edge!=0 with the variables filterLeftMbEdgeFlag, mbNum and tmp */
484     /* Note that Alpha_c, Beta_c and clipTable_c for chroma is already calculated */
485     Alpha = filterLeftMbEdgeFlag;
486     Beta = mbNum;
487     clipTable = (int *)tmp;
488 
489     GetStrength_HorizontalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
490 
491     for (edge = 1; edge < 4; edge++)  // 4 horicontal strips of 16 pel
492     {
493         //GetStrength(video, Strength, MbP, MbQ, 1, edge); // Strength for 4 blks in 1 stripe   1 => horizontal edge
494         if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0
495         {
496             if (Alpha > 0 && Beta > 0)
497             {
498 #ifdef USE_PRED_BLOCK
499                 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*20, Strength + (edge << 2),  Alpha, Beta, clipTable, 20);
500 #else
501                 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*pitch, Strength + (edge << 2),  Alpha, Beta, clipTable, pitch);
502 #endif
503             }
504 
505             if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
506             {
507 #ifdef USE_PRED_BLOCK
508                 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
509                 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
510 #else
511                 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
512                 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
513 #endif
514             }
515         }
516 
517     } //end edge
518 
519     return;
520 }
521 
522 /*
523  *****************************************************************************************************
524  * \brief   returns a buffer of 4 Strength values for one stripe in a mb (for different Frame types)
525  *****************************************************************************************************
526 */
527 
GetStrength_Edge0(uint8 * Strength,AVCMacroblock * MbP,AVCMacroblock * MbQ,int dir)528 void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir)
529 {
530     int tmp;
531     int16 *ptrQ, *ptrP;
532     void* vptr;
533     uint8 *pStrength;
534     void* refIdx;
535 
536     if (MbP->mbMode == AVC_I4 || MbP->mbMode == AVC_I16 ||
537             MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
538     {
539 
540         *((int*)Strength) = ININT_STRENGTH[0];      // Start with Strength=3. or Strength=4 for Mb-edge
541 
542     }
543     else // if not intra or SP-frame
544     {
545         *((int*)Strength) = 0;
546 
547         if (dir == 0)  // Vertical Edge 0
548         {
549 
550             //1. Check the ref_frame_id
551             refIdx = (void*) MbQ->RefIdx; //de-ref type-punned pointer fix
552             ptrQ = (int16*)refIdx;
553             refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer fix
554             ptrP = (int16*)refIdx;
555             pStrength = Strength;
556             if (ptrQ[0] != ptrP[1]) pStrength[0] = 1;
557             if (ptrQ[2] != ptrP[3]) pStrength[2] = 1;
558             pStrength[1] = pStrength[0];
559             pStrength[3] = pStrength[2];
560 
561             //2. Check the non-zero coeff blocks (4x4)
562             if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[3] != 0) pStrength[0] = 2;
563             if (MbQ->nz_coeff[4] != 0 || MbP->nz_coeff[7] != 0) pStrength[1] = 2;
564             if (MbQ->nz_coeff[8] != 0 || MbP->nz_coeff[11] != 0) pStrength[2] = 2;
565             if (MbQ->nz_coeff[12] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
566 
567             //3. Only need to check the mv difference
568             vptr = (void*)MbQ->mvL0;  // for deref type-punned pointer
569             ptrQ = (int16*)vptr;
570             ptrP = (int16*)(MbP->mvL0 + 3); // points to 4x4 block #3 (the 4th column)
571 
572             // 1st blk
573             if (*pStrength == 0)
574             {
575                 // check |mv difference| >= 4
576                 tmp = *ptrQ++ - *ptrP++;
577                 if (tmp < 0) tmp = -tmp;
578                 if (tmp >= 4) *pStrength = 1;
579 
580                 tmp = *ptrQ-- - *ptrP--;
581                 if (tmp < 0) tmp = -tmp;
582                 if (tmp >= 4) *pStrength = 1;
583             }
584 
585             pStrength++;
586             ptrQ += 8;
587             ptrP += 8;
588 
589             // 2nd blk
590             if (*pStrength == 0)
591             {
592                 // check |mv difference| >= 4
593                 tmp = *ptrQ++ - *ptrP++;
594                 if (tmp < 0) tmp = -tmp;
595                 if (tmp >= 4) *pStrength = 1;
596 
597                 tmp = *ptrQ-- - *ptrP--;
598                 if (tmp < 0) tmp = -tmp;
599                 if (tmp >= 4) *pStrength = 1;
600             }
601 
602             pStrength++;
603             ptrQ += 8;
604             ptrP += 8;
605 
606             // 3rd blk
607             if (*pStrength == 0)
608             {
609                 // check |mv difference| >= 4
610                 tmp = *ptrQ++ - *ptrP++;
611                 if (tmp < 0) tmp = -tmp;
612                 if (tmp >= 4) *pStrength = 1;
613 
614                 tmp = *ptrQ-- - *ptrP--;
615                 if (tmp < 0) tmp = -tmp;
616                 if (tmp >= 4) *pStrength = 1;
617             }
618 
619             pStrength++;
620             ptrQ += 8;
621             ptrP += 8;
622 
623             // 4th blk
624             if (*pStrength == 0)
625             {
626                 // check |mv difference| >= 4
627                 tmp = *ptrQ++ - *ptrP++;
628                 if (tmp < 0) tmp = -tmp;
629                 if (tmp >= 4) *pStrength = 1;
630 
631                 tmp = *ptrQ-- - *ptrP--;
632                 if (tmp < 0) tmp = -tmp;
633                 if (tmp >= 4) *pStrength = 1;
634             }
635         }
636         else   // Horizontal Edge 0
637         {
638 
639             //1. Check the ref_frame_id
640             refIdx = (void*)MbQ->RefIdx;  //de-ref type-punned pointer
641             ptrQ = (int16*)refIdx;
642             refIdx = (void*)MbP->RefIdx;  //de-ref type-punned pointer
643             ptrP = (int16*)refIdx;
644             pStrength = Strength;
645             if (ptrQ[0] != ptrP[2]) pStrength[0] = 1;
646             if (ptrQ[1] != ptrP[3]) pStrength[2] = 1;
647             pStrength[1] = pStrength[0];
648             pStrength[3] = pStrength[2];
649 
650             //2. Check the non-zero coeff blocks (4x4)
651             if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[12] != 0) pStrength[0] = 2;
652             if (MbQ->nz_coeff[1] != 0 || MbP->nz_coeff[13] != 0) pStrength[1] = 2;
653             if (MbQ->nz_coeff[2] != 0 || MbP->nz_coeff[14] != 0) pStrength[2] = 2;
654             if (MbQ->nz_coeff[3] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
655 
656             //3. Only need to check the mv difference
657             vptr = (void*)MbQ->mvL0;
658             ptrQ = (int16*)vptr;
659             ptrP = (int16*)(MbP->mvL0 + 12); // points to 4x4 block #12 (the 4th row)
660 
661             // 1st blk
662             if (*pStrength == 0)
663             {
664                 // check |mv difference| >= 4
665                 tmp = *ptrQ++ - *ptrP++;
666                 if (tmp < 0) tmp = -tmp;
667                 if (tmp >= 4) *pStrength = 1;
668 
669                 tmp = *ptrQ-- - *ptrP--;
670                 if (tmp < 0) tmp = -tmp;
671                 if (tmp >= 4) *pStrength = 1;
672             }
673 
674             pStrength++;
675             ptrQ += 2;
676             ptrP += 2;
677 
678             // 2nd blk
679             if (*pStrength  == 0)
680             {
681                 // check |mv difference| >= 4
682                 tmp = *ptrQ++ - *ptrP++;
683                 if (tmp < 0) tmp = -tmp;
684                 if (tmp >= 4) *pStrength = 1;
685 
686                 tmp = *ptrQ-- - *ptrP--;
687                 if (tmp < 0) tmp = -tmp;
688                 if (tmp >= 4) *pStrength = 1;
689             }
690 
691             pStrength++;
692             ptrQ += 2;
693             ptrP += 2;
694 
695             // 3rd blk
696             if (*pStrength  == 0)
697             {
698                 // check |mv difference| >= 4
699                 tmp = *ptrQ++ - *ptrP++;
700                 if (tmp < 0) tmp = -tmp;
701                 if (tmp >= 4) *pStrength = 1;
702 
703                 tmp = *ptrQ-- - *ptrP--;
704                 if (tmp < 0) tmp = -tmp;
705                 if (tmp >= 4) *pStrength = 1;
706             }
707 
708             pStrength++;
709             ptrQ += 2;
710             ptrP += 2;
711 
712             // 4th blk
713             if (*pStrength  == 0)
714             {
715                 // check |mv difference| >= 4
716                 tmp = *ptrQ++ - *ptrP++;
717                 if (tmp < 0) tmp = -tmp;
718                 if (tmp >= 4) *pStrength = 1;
719 
720                 tmp = *ptrQ-- - *ptrP--;
721                 if (tmp < 0) tmp = -tmp;
722                 if (tmp >= 4) *pStrength = 1;
723             }
724 
725         } /* end of: else if(dir == 0) */
726 
727     } /* end of: if( !(MbP->mbMode == AVC_I4 ...) */
728 }
729 
730 
GetStrength_VerticalEdges(uint8 * Strength,AVCMacroblock * MbQ)731 void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ)
732 {
733     int     idx, tmp;
734     int16   *ptr, *pmvx, *pmvy;
735     uint8   *pnz;
736     uint8   *pStrength, *pStr;
737     void* refIdx;
738 
739     if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
740     {
741         *((int*)Strength)     = ININT_STRENGTH[1];      // Start with Strength=3. or Strength=4 for Mb-edge
742         *((int*)(Strength + 4)) = ININT_STRENGTH[2];
743         *((int*)(Strength + 8)) = ININT_STRENGTH[3];
744     }
745     else   // Not intra or SP-frame
746     {
747 
748         *((int*)Strength)     = 0; // for non-intra MB, strength = 0, 1 or 2.
749         *((int*)(Strength + 4)) = 0;
750         *((int*)(Strength + 8)) = 0;
751 
752         //1. Check the ref_frame_id
753         refIdx = (void*)MbQ->RefIdx;  //de-ref type-punned pointer fix
754         ptr = (int16*)refIdx;
755         pStrength = Strength;
756         if (ptr[0] != ptr[1]) pStrength[4] = 1;
757         if (ptr[2] != ptr[3]) pStrength[6] = 1;
758         pStrength[5] = pStrength[4];
759         pStrength[7] = pStrength[6];
760 
761         //2. Check the nz_coeff block and mv difference
762         pmvx = (int16*)(MbQ->mvL0 + 1); // points to 4x4 block #1,not #0
763         pmvy = pmvx + 1;
764         for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
765         {
766             // first/third row : 1,2,3 or 9,10,12
767             // Strength = 2 for a whole row
768             pnz = MbQ->nz_coeff + (idx << 2);
769             if (*pnz++ != 0) *pStrength = 2;
770             if (*pnz++ != 0)
771             {
772                 *pStrength = 2;
773                 *(pStrength + 4) = 2;
774             }
775             if (*pnz++ != 0)
776             {
777                 *(pStrength + 4) = 2;
778                 *(pStrength + 8) = 2;
779             }
780             if (*pnz != 0) *(pStrength + 8) = 2;
781 
782             // Then Strength = 1
783             if (*pStrength == 0)
784             {
785                 //within the same 8x8 block, no need to check the reference id
786                 //only need to check the |mv difference| >= 4
787                 tmp = *pmvx - *(pmvx - 2);
788                 if (tmp < 0) tmp = -tmp;
789                 if (tmp >= 4) *pStrength = 1;
790 
791                 tmp = *pmvy - *(pmvy - 2);
792                 if (tmp < 0) tmp = -tmp;
793                 if (tmp >= 4) *pStrength = 1;
794             }
795 
796             pmvx += 2;
797             pmvy += 2;
798             pStr = pStrength + 4;
799 
800             if (*pStr == 0)
801             {
802                 //check the |mv difference| >= 4
803                 tmp = *pmvx - *(pmvx - 2);
804                 if (tmp < 0) tmp = -tmp;
805                 if (tmp >= 4) *pStr = 1;
806 
807                 tmp = *pmvy - *(pmvy - 2);
808                 if (tmp < 0) tmp = -tmp;
809                 if (tmp >= 4) *pStr = 1;
810             }
811 
812             pmvx += 2;
813             pmvy += 2;
814             pStr = pStrength + 8;
815 
816             if (*pStr == 0)
817             {
818                 //within the same 8x8 block, no need to check the reference id
819                 //only need to check the |mv difference| >= 4
820                 tmp = *pmvx - *(pmvx - 2);
821                 if (tmp < 0) tmp = -tmp;
822                 if (tmp >= 4) *pStr = 1;
823 
824                 tmp = *pmvy - *(pmvy - 2);
825                 if (tmp < 0) tmp = -tmp;
826                 if (tmp >= 4) *pStr = 1;
827             }
828 
829             // Second/fourth row: 5,6,7 or 14,15,16
830             // Strength = 2 for a whole row
831             pnz = MbQ->nz_coeff + ((idx + 1) << 2);
832             if (*pnz++ != 0) *(pStrength + 1) = 2;
833             if (*pnz++ != 0)
834             {
835                 *(pStrength + 1) = 2;
836                 *(pStrength + 5) = 2;
837             }
838             if (*pnz++ != 0)
839             {
840                 *(pStrength + 5) = 2;
841                 *(pStrength + 9) = 2;
842             }
843             if (*pnz != 0) *(pStrength + 9) = 2;
844 
845             // Then Strength = 1
846             pmvx += 4;
847             pmvy += 4;
848             pStr = pStrength + 1;
849             if (*pStr == 0)
850             {
851                 //within the same 8x8 block, no need to check the reference id
852                 //only need to check the |mv difference| >= 4
853                 tmp = *pmvx - *(pmvx - 2);
854                 if (tmp < 0) tmp = -tmp;
855                 if (tmp >= 4) *pStr = 1;
856 
857                 tmp = *pmvy - *(pmvy - 2);
858                 if (tmp < 0) tmp = -tmp;
859                 if (tmp >= 4) *pStr = 1;
860             }
861 
862             pmvx += 2;
863             pmvy += 2;
864             pStr = pStrength + 5;
865 
866             if (*pStr == 0)
867             {
868                 //check the |mv difference| >= 4
869                 tmp = *pmvx - *(pmvx - 2);
870                 if (tmp < 0) tmp = -tmp;
871                 if (tmp >= 4) *pStr = 1;
872 
873                 tmp = *pmvy - *(pmvy - 2);
874                 if (tmp < 0) tmp = -tmp;
875                 if (tmp >= 4) *pStr = 1;
876             }
877 
878             pmvx += 2;
879             pmvy += 2;
880             pStr = pStrength + 9;
881 
882             if (*pStr == 0)
883             {
884                 //within the same 8x8 block, no need to check the reference id
885                 //only need to check the |mv difference| >= 4
886                 tmp = *pmvx - *(pmvx - 2);
887                 if (tmp < 0) tmp = -tmp;
888                 if (tmp >= 4) *pStr = 1;
889 
890                 tmp = *pmvy - *(pmvy - 2);
891                 if (tmp < 0) tmp = -tmp;
892                 if (tmp >= 4) *pStr = 1;
893             }
894 
895             // update some variables for the next two rows
896             pmvx += 4;
897             pmvy += 4;
898             pStrength += 2;
899 
900         } /* end of: for(idx=0; idx<2; idx++) */
901 
902     } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
903 }
904 
905 
GetStrength_HorizontalEdges(uint8 Strength[12],AVCMacroblock * MbQ)906 void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ)
907 {
908     int     idx, tmp;
909     int16   *ptr, *pmvx, *pmvy;
910     uint8   *pStrength, *pStr;
911     void* refIdx;
912 
913     if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
914     {
915         *((int*)Strength)     = ININT_STRENGTH[1];      // Start with Strength=3. or Strength=4 for Mb-edge
916         *((int*)(Strength + 4)) = ININT_STRENGTH[2];
917         *((int*)(Strength + 8)) = ININT_STRENGTH[3];
918     }
919     else   // Not intra or SP-frame
920     {
921 
922         *((int*)Strength)     = 0; // for non-intra MB, strength = 0, 1 or 2.
923         *((int*)(Strength + 4)) = 0; // for non-intra MB, strength = 0, 1 or 2.
924         *((int*)(Strength + 8)) = 0; // for non-intra MB, strength = 0, 1 or 2.
925 
926 
927         //1. Check the ref_frame_id
928         refIdx = (void*) MbQ->RefIdx; // de-ref type-punned fix
929         ptr = (int16*) refIdx;
930         pStrength = Strength;
931         if (ptr[0] != ptr[2]) pStrength[4] = 1;
932         if (ptr[1] != ptr[3]) pStrength[6] = 1;
933         pStrength[5] = pStrength[4];
934         pStrength[7] = pStrength[6];
935 
936         //2. Check the nz_coeff block and mv difference
937         pmvx = (int16*)(MbQ->mvL0 + 4); // points to 4x4 block #4,not #0
938         pmvy = pmvx + 1;
939         for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
940         {
941             // first/third row : 1,2,3 or 9,10,12
942             // Strength = 2 for a whole row
943             if (MbQ->nz_coeff[idx] != 0) *pStrength = 2;
944             if (MbQ->nz_coeff[4+idx] != 0)
945             {
946                 *pStrength = 2;
947                 *(pStrength + 4) = 2;
948             }
949             if (MbQ->nz_coeff[8+idx] != 0)
950             {
951                 *(pStrength + 4) = 2;
952                 *(pStrength + 8) = 2;
953             }
954             if (MbQ->nz_coeff[12+idx] != 0) *(pStrength + 8) = 2;
955 
956             // Then Strength = 1
957             if (*pStrength == 0)
958             {
959                 //within the same 8x8 block, no need to check the reference id
960                 //only need to check the |mv difference| >= 4
961                 tmp = *pmvx - *(pmvx - 8);
962                 if (tmp < 0) tmp = -tmp;
963                 if (tmp >= 4) *pStrength = 1;
964 
965                 tmp = *pmvy - *(pmvy - 8);
966                 if (tmp < 0) tmp = -tmp;
967                 if (tmp >= 4) *pStrength = 1;
968             }
969 
970             pmvx += 8;
971             pmvy += 8;
972             pStr = pStrength + 4;
973 
974             if (*pStr == 0)
975             {
976                 //check the |mv difference| >= 4
977                 tmp = *pmvx - *(pmvx - 8);
978                 if (tmp < 0) tmp = -tmp;
979                 if (tmp >= 4) *pStr = 1;
980 
981                 tmp = *pmvy - *(pmvy - 8);
982                 if (tmp < 0) tmp = -tmp;
983                 if (tmp >= 4) *pStr = 1;
984             }
985 
986             pmvx += 8;
987             pmvy += 8;
988             pStr = pStrength + 8;
989 
990             if (*pStr == 0)
991             {
992                 //within the same 8x8 block, no need to check the reference id
993                 //only need to check the |mv difference| >= 4
994                 tmp = *pmvx - *(pmvx - 8);
995                 if (tmp < 0) tmp = -tmp;
996                 if (tmp >= 4) *pStr = 1;
997 
998                 tmp = *pmvy - *(pmvy - 8);
999                 if (tmp < 0) tmp = -tmp;
1000                 if (tmp >= 4) *pStr = 1;
1001             }
1002 
1003             // Second/fourth row: 5,6,7 or 14,15,16
1004             // Strength = 2 for a whole row
1005             if (MbQ->nz_coeff[idx+1] != 0) *(pStrength + 1) = 2;
1006             if (MbQ->nz_coeff[4+idx+1] != 0)
1007             {
1008                 *(pStrength + 1) = 2;
1009                 *(pStrength + 5) = 2;
1010             }
1011             if (MbQ->nz_coeff[8+idx+1] != 0)
1012             {
1013                 *(pStrength + 5) = 2;
1014                 *(pStrength + 9) = 2;
1015             }
1016             if (MbQ->nz_coeff[12+idx+1] != 0) *(pStrength + 9) = 2;
1017 
1018             // Then Strength = 1
1019             pmvx -= 14;
1020             pmvy -= 14; // -14 = -16 + 2
1021             pStr = pStrength + 1;
1022             if (*pStr == 0)
1023             {
1024                 //within the same 8x8 block, no need to check the reference id
1025                 //only need to check the |mv difference| >= 4
1026                 tmp = *pmvx - *(pmvx - 8);
1027                 if (tmp < 0) tmp = -tmp;
1028                 if (tmp >= 4) *pStr = 1;
1029 
1030                 tmp = *pmvy - *(pmvy - 8);
1031                 if (tmp < 0) tmp = -tmp;
1032                 if (tmp >= 4) *pStr = 1;
1033             }
1034 
1035             pmvx += 8;
1036             pmvy += 8;
1037             pStr = pStrength + 5;
1038 
1039             if (*pStr == 0)
1040             {
1041                 //check the |mv difference| >= 4
1042                 tmp = *pmvx - *(pmvx - 8);
1043                 if (tmp < 0) tmp = -tmp;
1044                 if (tmp >= 4) *pStr = 1;
1045 
1046                 tmp = *pmvy - *(pmvy - 8);
1047                 if (tmp < 0) tmp = -tmp;
1048                 if (tmp >= 4) *pStr = 1;
1049             }
1050 
1051             pmvx += 8;
1052             pmvy += 8;
1053             pStr = pStrength + 9;
1054 
1055             if (*pStr == 0)
1056             {
1057                 //within the same 8x8 block, no need to check the reference id
1058                 //only need to check the |mv difference| >= 4
1059                 tmp = *pmvx - *(pmvx - 8);
1060                 if (tmp < 0) tmp = -tmp;
1061                 if (tmp >= 4) *pStr = 1;
1062 
1063                 tmp = *pmvy - *(pmvy - 8);
1064                 if (tmp < 0) tmp = -tmp;
1065                 if (tmp >= 4) *pStr = 1;
1066             }
1067 
1068             // update some variables for the next two rows
1069             pmvx -= 14;
1070             pmvy -= 14; // -14 = -16 + 2
1071             pStrength += 2;
1072 
1073         } /* end of: for(idx=0; idx<2; idx++) */
1074 
1075     } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
1076 }
1077 
1078 /*
1079  *****************************************************************************************
1080  * \brief  Filters one edge of 16 (luma) or 8 (chroma) pel
1081  *****************************************************************************************
1082 */
1083 
EdgeLoop_Luma_horizontal(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1084 void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1085 {
1086     int  pel, ap = 0, aq = 0, Strng;
1087     int  C0, c0, dif, AbsDelta, tmp, tmp1;
1088     int  L2 = 0, L1, L0, R0, R1, R2 = 0, RL0;
1089 
1090 
1091     if (Strength[0] == 4)  /* INTRA strong filtering */
1092     {
1093         for (pel = 0; pel < 16; pel++)
1094         {
1095             R0  = SrcPtr[0];
1096             R1  = SrcPtr[pitch];
1097             L0  = SrcPtr[-pitch];
1098             L1  = SrcPtr[-(pitch<<1)];
1099 
1100             // |R0 - R1| < Beta
1101             tmp1 = R0 - R1;
1102             if (tmp1 < 0) tmp1 = -tmp1;
1103             tmp = (tmp1 - Beta);
1104 
1105             //|L0 - L1| < Beta
1106             tmp1 = L0 - L1;
1107             if (tmp1 < 0) tmp1 = -tmp1;
1108             tmp &= (tmp1 - Beta);
1109 
1110             //|R0 - L0| < Alpha
1111             AbsDelta = R0 - L0;
1112             if (AbsDelta < 0) AbsDelta = -AbsDelta;
1113             tmp &= (AbsDelta - Alpha);
1114 
1115             if (tmp < 0)
1116             {
1117                 AbsDelta -= ((Alpha >> 2) + 2);
1118                 R2 = SrcPtr[pitch<<1]; //inc2
1119                 L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
1120 
1121                 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1122                 tmp = R0 - R2;
1123                 if (tmp < 0) tmp = -tmp;
1124                 aq = AbsDelta & (tmp - Beta);
1125 
1126                 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1127                 tmp = L0 - L2;
1128                 if (tmp < 0) tmp = -tmp;
1129                 ap = AbsDelta & (tmp - Beta);
1130 
1131                 if (aq < 0)
1132                 {
1133                     tmp = R1 + R0 + L0;
1134                     SrcPtr[0] = (L1 + (tmp << 1) +  R2 + 4) >> 3;
1135                     tmp += R2;
1136                     SrcPtr[pitch]  = (tmp + 2) >> 2;
1137                     SrcPtr[pitch<<1] = (((SrcPtr[(pitch+(pitch<<1))] + R2) << 1) + tmp + 4) >> 3;
1138                 }
1139                 else
1140                     SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
1141 
1142                 if (ap < 0)
1143                 {
1144                     tmp = L1 + R0 + L0;
1145                     SrcPtr[-pitch]  = (R1 + (tmp << 1) +  L2 + 4) >> 3;
1146                     tmp += L2;
1147                     SrcPtr[-(pitch<<1)] = (tmp + 2) >> 2;
1148                     SrcPtr[-(pitch+(pitch<<1))] = (((SrcPtr[-(pitch<<2)] + L2) << 1) + tmp + 4) >> 3;
1149                 }
1150                 else
1151                     SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
1152 
1153             } /* if(tmp < 0) */
1154 
1155             SrcPtr ++; // Increment to next set of pixel
1156 
1157         } /* end of: for(pel=0; pel<16; pel++) */
1158 
1159     } /* if(Strength[0] == 4) */
1160 
1161     else   /* Normal filtering */
1162     {
1163         for (pel = 0; pel < 16; pel++)
1164         {
1165             Strng = Strength[pel >> 2];
1166             if (Strng)
1167             {
1168                 R0  = SrcPtr[0];
1169                 R1  = SrcPtr[pitch];
1170                 L0  = SrcPtr[-pitch];
1171                 L1  = SrcPtr[-(pitch<<1)]; // inc2
1172 
1173                 //|R0 - L0| < Alpha
1174                 tmp1 = R0 - L0;
1175                 if (tmp1 < 0) tmp1 = -tmp1;
1176                 tmp = (tmp1 - Alpha);
1177 
1178                 // |R0 - R1| < Beta
1179                 tmp1 = R0 - R1;
1180                 if (tmp1 < 0) tmp1 = -tmp1;
1181                 tmp &= (tmp1 - Beta);
1182 
1183                 //|L0 - L1| < Beta
1184                 tmp1 = L0 - L1;
1185                 if (tmp1 < 0) tmp1 = -tmp1;
1186                 tmp &= (tmp1 - Beta);
1187 
1188                 if (tmp < 0)
1189                 {
1190                     R2 = SrcPtr[pitch<<1]; //inc2
1191                     L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
1192 
1193                     // |R0 - R2| < Beta
1194                     tmp = R0 - R2;
1195                     if (tmp < 0) tmp = -tmp;
1196                     aq = tmp - Beta;
1197 
1198                     // |L0 - L2| < Beta
1199                     tmp = L0 - L2;
1200                     if (tmp < 0) tmp = -tmp;
1201                     ap = tmp - Beta;
1202 
1203 
1204                     c0 = C0 = clipTable[Strng];
1205                     if (ap < 0) c0++;
1206                     if (aq < 0) c0++;
1207 
1208                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1209                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1210                     tmp = dif + c0;
1211                     if ((uint)tmp > (uint)c0 << 1)
1212                     {
1213                         tmp = ~(tmp >> 31);
1214                         dif = (tmp & (c0 << 1)) - c0;
1215                     }
1216 
1217                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
1218                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1219                     RL0 = R0 + L0;
1220                     R0 -= dif;
1221                     L0 += dif;
1222                     if ((uint)R0 > 255)
1223                     {
1224                         tmp = ~(R0 >> 31);
1225                         R0 = tmp & 255;
1226                     }
1227                     if ((uint)L0 > 255)
1228                     {
1229                         tmp = ~(L0 >> 31);
1230                         L0 = tmp & 255;
1231                     }
1232                     SrcPtr[-pitch] = L0;
1233                     SrcPtr[0] = R0;
1234 
1235                     if (C0 != 0) /* Multiple zeros in the clip tables */
1236                     {
1237                         if (aq < 0)  // SrcPtr[inc]   += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
1238                         {
1239                             R2 = (R2 + ((RL0 + 1) >> 1) - (R1 << 1)) >> 1;
1240                             tmp = R2 + C0;
1241                             if ((uint)tmp > (uint)C0 << 1)
1242                             {
1243                                 tmp = ~(tmp >> 31);
1244                                 R2 = (tmp & (C0 << 1)) - C0;
1245                             }
1246                             SrcPtr[pitch] += R2;
1247                         }
1248 
1249                         if (ap < 0)  //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
1250                         {
1251                             L2 = (L2 + ((RL0 + 1) >> 1) - (L1 << 1)) >> 1;
1252                             tmp = L2 + C0;
1253                             if ((uint)tmp > (uint)C0 << 1)
1254                             {
1255                                 tmp = ~(tmp >> 31);
1256                                 L2 = (tmp & (C0 << 1)) - C0;
1257                             }
1258                             SrcPtr[-(pitch<<1)] += L2;
1259                         }
1260                     }
1261 
1262                 } /* if(tmp < 0) */
1263 
1264             } /* end of:  if((Strng = Strength[pel >> 2])) */
1265 
1266             SrcPtr ++; // Increment to next set of pixel
1267 
1268         } /* for(pel=0; pel<16; pel++) */
1269 
1270     } /* else if(Strength[0] == 4) */
1271 }
1272 
EdgeLoop_Luma_vertical(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1273 void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1274 {
1275     int  pel, ap = 1, aq = 1;
1276     int  C0, c0, dif, AbsDelta, Strng, tmp, tmp1;
1277     int  L2 = 0, L1, L0, R0, R1, R2 = 0;
1278     uint8 *ptr, *ptr1;
1279     register uint R_in, L_in;
1280     uint R_out, L_out;
1281 
1282 
1283     if (Strength[0] == 4)  /* INTRA strong filtering */
1284     {
1285 
1286         for (pel = 0; pel < 16; pel++)
1287         {
1288 
1289             // Read 8 pels
1290             R_in = *((uint *)SrcPtr);       // R_in = {R3, R2, R1, R0}
1291             L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
1292             R1   = (R_in >> 8) & 0xff;
1293             R0   = R_in & 0xff;
1294             L0   = L_in >> 24;
1295             L1   = (L_in >> 16) & 0xff;
1296 
1297             // |R0 - R1| < Beta
1298             tmp1 = (R_in & 0xff) - R1;
1299             if (tmp1 < 0) tmp1 = -tmp1;
1300             tmp = (tmp1 - Beta);
1301 
1302 
1303             //|L0 - L1| < Beta
1304             tmp1 = (L_in >> 24) - L1;
1305             if (tmp1 < 0) tmp1 = -tmp1;
1306             tmp &= (tmp1 - Beta);
1307 
1308             //|R0 - L0| < Alpha
1309             AbsDelta = (R_in & 0xff) - (L_in >> 24);
1310             if (AbsDelta < 0) AbsDelta = -AbsDelta;
1311             tmp &= (AbsDelta - Alpha);
1312 
1313             if (tmp < 0)
1314             {
1315                 AbsDelta -= ((Alpha >> 2) + 2);
1316                 R2   = (R_in >> 16) & 0xff;
1317                 L2   = (L_in >> 8) & 0xff;
1318 
1319                 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1320                 tmp1 = (R_in & 0xff) - R2;
1321                 if (tmp1 < 0) tmp1 = -tmp1;
1322                 aq = AbsDelta & (tmp1 - Beta);
1323 
1324                 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1325                 tmp1 = (L_in >> 24) - L2;
1326                 if (tmp1 < 0) tmp1 = -tmp1;
1327                 ap = AbsDelta & (tmp1 - Beta);
1328 
1329 
1330                 ptr = SrcPtr;
1331                 if (aq < 0)
1332                 {
1333                     R_out = (R_in >> 24) << 24; // Keep R3 at the fourth byte
1334 
1335                     tmp  = R0 + L0 + R1;
1336                     R_out |= (((tmp << 1) +  L1 + R2 + 4) >> 3);
1337                     tmp += R2;
1338                     R_out |= (((tmp + 2) >> 2) << 8);
1339                     tmp1 = ((R_in >> 24) + R2) << 1;
1340                     R_out |= (((tmp1 + tmp + 4) >> 3) << 16);
1341 
1342                     *((uint *)SrcPtr) = R_out;
1343                 }
1344                 else
1345                     *ptr = ((R1 << 1) + R0 + L1 + 2) >> 2;
1346 
1347 
1348                 if (ap < 0)
1349                 {
1350                     L_out = (L_in << 24) >> 24; // Keep L3 at the first byte
1351 
1352                     tmp  = R0 + L0 + L1;
1353                     L_out |= ((((tmp << 1) + R1 + L2 + 4) >> 3) << 24);
1354                     tmp += L2;
1355                     L_out |= (((tmp + 2) >> 2) << 16);
1356                     tmp1 = ((L_in & 0xff) + L2) << 1;
1357                     L_out |= (((tmp1 + tmp + 4) >> 3) << 8);
1358 
1359                     *((uint *)(SrcPtr - 4)) = L_out;
1360                 }
1361                 else
1362                     *(--ptr) = ((L1 << 1) + L0 + R1 + 2) >> 2;
1363 
1364             } /* if(tmp < 0) */
1365 
1366             SrcPtr += pitch;    // Increment to next set of pixel
1367 
1368         } /* end of: for(pel=0; pel<16; pel++) */
1369 
1370     } /* if(Strength[0] == 4) */
1371 
1372     else   /* Normal filtering */
1373     {
1374 
1375         for (pel = 0; pel < 16; pel++)
1376         {
1377             Strng = Strength[pel >> 2];
1378             if (Strng)
1379             {
1380                 // Read 8 pels
1381                 R_in = *((uint *)SrcPtr);       // R_in = {R3, R2, R1, R0}
1382                 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
1383                 R1   = (R_in >> 8) & 0xff;
1384                 R0   = R_in & 0xff;
1385                 L0   = L_in >> 24;
1386                 L1   = (L_in >> 16) & 0xff;
1387 
1388                 //|R0 - L0| < Alpha
1389                 tmp = R0 - L0;
1390                 if (tmp < 0) tmp = -tmp;
1391                 tmp -= Alpha;
1392 
1393                 // |R0 - R1| < Beta
1394                 tmp1 = R0 - R1;
1395                 if (tmp1 < 0) tmp1 = -tmp1;
1396                 tmp &= (tmp1 - Beta);
1397 
1398                 //|L0 - L1| < Beta
1399                 tmp1 = L0 - L1;
1400                 if (tmp1 < 0) tmp1 = -tmp1;
1401                 tmp &= (tmp1 - Beta);
1402 
1403                 if (tmp < 0)
1404                 {
1405                     L2 = SrcPtr[-3];
1406                     R2 = SrcPtr[2];
1407 
1408                     // |R0 - R2| < Beta
1409                     tmp = R0 - R2;
1410                     if (tmp < 0) tmp = -tmp;
1411                     aq = tmp - Beta;
1412 
1413                     // |L0 - L2| < Beta
1414                     tmp = L0 - L2;
1415                     if (tmp < 0) tmp = -tmp;
1416                     ap = tmp - Beta;
1417 
1418 
1419                     c0 = C0 = clipTable[Strng];
1420                     if (ap < 0) c0++;
1421                     if (aq < 0) c0++;
1422 
1423                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1424                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1425                     tmp = dif + c0;
1426                     if ((uint)tmp > (uint)c0 << 1)
1427                     {
1428                         tmp = ~(tmp >> 31);
1429                         dif = (tmp & (c0 << 1)) - c0;
1430                     }
1431 
1432                     ptr = SrcPtr;
1433                     ptr1 = SrcPtr - 1;
1434                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
1435                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1436                     R_in = R0 - dif;
1437                     L_in = L0 + dif; /* cannot re-use R0 and L0 here */
1438                     if ((uint)R_in > 255)
1439                     {
1440                         tmp = ~((int)R_in >> 31);
1441                         R_in = tmp & 255;
1442                     }
1443                     if ((uint)L_in > 255)
1444                     {
1445                         tmp = ~((int)L_in >> 31);
1446                         L_in = tmp & 255;
1447                     }
1448                     *ptr1-- = L_in;
1449                     *ptr++  = R_in;
1450 
1451                     if (C0 != 0) // Multiple zeros in the clip tables
1452                     {
1453                         if (ap < 0)  //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
1454                         {
1455                             L2 = (L2 + ((R0 + L0 + 1) >> 1) - (L1 << 1)) >> 1;
1456                             tmp = L2 + C0;
1457                             if ((uint)tmp > (uint)C0 << 1)
1458                             {
1459                                 tmp = ~(tmp >> 31);
1460                                 L2 = (tmp & (C0 << 1)) - C0;
1461                             }
1462                             *ptr1 += L2;
1463                         }
1464 
1465                         if (aq < 0)  // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
1466                         {
1467                             R2 = (R2 + ((R0 + L0 + 1) >> 1) - (R1 << 1)) >> 1;
1468                             tmp = R2 + C0;
1469                             if ((uint)tmp > (uint)C0 << 1)
1470                             {
1471                                 tmp = ~(tmp >> 31);
1472                                 R2 = (tmp & (C0 << 1)) - C0;
1473                             }
1474                             *ptr += R2;
1475                         }
1476                     }
1477 
1478                 } /* if(tmp < 0) */
1479 
1480             } /* end of:  if((Strng = Strength[pel >> 2])) */
1481 
1482             SrcPtr += pitch;    // Increment to next set of pixel
1483 
1484         } /* for(pel=0; pel<16; pel++) */
1485 
1486     } /* else if(Strength[0] == 4) */
1487 
1488 }
1489 
EdgeLoop_Chroma_vertical(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1490 void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1491 {
1492     int     pel, Strng;
1493     int     c0, dif;
1494     int     L1, L0, R0, R1, tmp, tmp1;
1495     uint8   *ptr;
1496     uint    R_in, L_in;
1497 
1498 
1499     for (pel = 0; pel < 16; pel++)
1500     {
1501         Strng = Strength[pel>>2];
1502         if (Strng)
1503         {
1504             // Read 8 pels
1505             R_in = *((uint *)SrcPtr);       // R_in = {R3, R2, R1, R0}
1506             L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
1507             R1   = (R_in >> 8) & 0xff;
1508             R0   = R_in & 0xff;
1509             L0   = L_in >> 24;
1510             L1   = (L_in >> 16) & 0xff;
1511 
1512             // |R0 - R1| < Beta
1513             tmp1 = R0 - R1;
1514             if (tmp1 < 0) tmp1 = -tmp1;
1515             tmp = (tmp1 - Beta);
1516 
1517             //|L0 - L1| < Beta
1518             tmp1 = L0 - L1;
1519             if (tmp1 < 0) tmp1 = -tmp1;
1520             tmp &= (tmp1 - Beta);
1521 
1522             //|R0 - L0| < Alpha
1523             tmp1 = R0 - L0;
1524             if (tmp1 < 0) tmp1 = -tmp1;
1525             tmp &= (tmp1 - Alpha);
1526 
1527             if (tmp < 0)
1528             {
1529                 ptr = SrcPtr;
1530                 if (Strng == 4) /* INTRA strong filtering */
1531                 {
1532                     *ptr-- = ((R1 << 1) + R0 + L1 + 2) >> 2;
1533                     *ptr   = ((L1 << 1) + L0 + R1 + 2) >> 2;
1534                 }
1535                 else  /* normal filtering */
1536                 {
1537                     c0  = clipTable[Strng] + 1;
1538                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1539                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1540                     tmp = dif + c0;
1541                     if ((uint)tmp > (uint)c0 << 1)
1542                     {
1543                         tmp = ~(tmp >> 31);
1544                         dif = (tmp & (c0 << 1)) - c0;
1545                     }
1546 
1547                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
1548                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1549                     L0 += dif;
1550                     R0 -= dif;
1551                     if ((uint)L0 > 255)
1552                     {
1553                         tmp = ~(L0 >> 31);
1554                         L0 = tmp & 255;
1555                     }
1556                     if ((uint)R0 > 255)
1557                     {
1558                         tmp = ~(R0 >> 31);
1559                         R0 = tmp & 255;
1560                     }
1561 
1562                     *ptr-- = R0;
1563                     *ptr = L0;
1564                 }
1565             }
1566             pel ++;
1567             SrcPtr += pitch;   // Increment to next set of pixel
1568 
1569         } /* end of: if((Strng = Strength[pel >> 2])) */
1570         else
1571         {
1572             pel += 3;
1573             SrcPtr += (pitch << 1); //PtrInc << 1;
1574         }
1575 
1576     } /* end of: for(pel=0; pel<16; pel++) */
1577 }
1578 
1579 
EdgeLoop_Chroma_horizontal(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1580 void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1581 {
1582     int  pel, Strng;
1583     int  c0, dif;
1584     int  L1, L0, R0, R1, tmp, tmp1;
1585 
1586     for (pel = 0; pel < 16; pel++)
1587     {
1588         Strng = Strength[pel>>2];
1589         if (Strng)
1590         {
1591             R0  = SrcPtr[0];
1592             L0  = SrcPtr[-pitch];
1593             L1  = SrcPtr[-(pitch<<1)]; //inc2
1594             R1  = SrcPtr[pitch];
1595 
1596             // |R0 - R1| < Beta
1597             tmp1 = R0 - R1;
1598             if (tmp1 < 0) tmp1 = -tmp1;
1599             tmp = (tmp1 - Beta);
1600 
1601             //|L0 - L1| < Beta
1602             tmp1 = L0 - L1;
1603             if (tmp1 < 0) tmp1 = -tmp1;
1604             tmp &= (tmp1 - Beta);
1605 
1606             //|R0 - L0| < Alpha
1607             tmp1 = R0 - L0;
1608             if (tmp1 < 0) tmp1 = -tmp1;
1609             tmp &= (tmp1 - Alpha);
1610 
1611             if (tmp < 0)
1612             {
1613                 if (Strng == 4) /* INTRA strong filtering */
1614                 {
1615                     SrcPtr[0]      = ((R1 << 1) + R0 + L1 + 2) >> 2;
1616                     SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
1617                 }
1618                 else  /* normal filtering */
1619                 {
1620                     c0  = clipTable[Strng] + 1;
1621                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1622                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1623                     tmp = dif + c0;
1624                     if ((uint)tmp > (uint)c0 << 1)
1625                     {
1626                         tmp = ~(tmp >> 31);
1627                         dif = (tmp & (c0 << 1)) - c0;
1628                     }
1629 
1630                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1631                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
1632                     L0 += dif;
1633                     R0 -= dif;
1634                     if ((uint)L0 > 255)
1635                     {
1636                         tmp = ~(L0 >> 31);
1637                         L0 = tmp & 255;
1638                     }
1639                     if ((uint)R0 > 255)
1640                     {
1641                         tmp = ~(R0 >> 31);
1642                         R0 = tmp & 255;
1643                     }
1644                     SrcPtr[0] = R0;
1645                     SrcPtr[-pitch] = L0;
1646                 }
1647             }
1648 
1649             pel ++;
1650             SrcPtr ++; // Increment to next set of pixel
1651 
1652         } /* end of: if((Strng = Strength[pel >> 2])) */
1653         else
1654         {
1655             pel += 3;
1656             SrcPtr += 2;
1657         }
1658 
1659     } /* end of: for(pel=0; pel<16; pel++) */
1660 }
1661 
1662 
1663 
1664 
1665