1 /*!
2 * \copy
3 * Copyright (c) 2010-2013, Cisco Systems
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * \file svc_preprocess.h
32 *
33 * \brief svc denoising
34 *
35 * \date 4/1/2010 Created
36 *
37 */
38
39 #include "denoise.h"
40
41 WELSVP_NAMESPACE_BEGIN
42
BilateralLumaFilter8_c(uint8_t * pSample,int32_t iStride)43 void BilateralLumaFilter8_c (uint8_t* pSample, int32_t iStride) {
44 int32_t nSum = 0, nTotWeight = 0;
45 int32_t iCenterSample = *pSample;
46 uint8_t* pCurLine = pSample - iStride - DENOISE_GRAY_RADIUS;
47 int32_t x, y;
48 int32_t iCurSample, iCurWeight, iGreyDiff;
49 uint8_t aSample[8];
50
51 for (int32_t i = 0; i < 8; i++) {
52 nSum = 0;
53 nTotWeight = 0;
54 iCenterSample = *pSample;
55 pCurLine = pSample - iStride - DENOISE_GRAY_RADIUS;
56 for (y = 0; y < 3; y++) {
57 for (x = 0; x < 3; x++) {
58 if (x == 1 && y == 1) continue; // except center point
59 iCurSample = pCurLine[x];
60 iCurWeight = WELS_ABS (iCurSample - iCenterSample);
61 iGreyDiff = 32 - iCurWeight;
62 if (iGreyDiff < 0) continue;
63 else iCurWeight = (iGreyDiff * iGreyDiff) >> 5;
64 nSum += iCurSample * iCurWeight;
65 nTotWeight += iCurWeight;
66 }
67 pCurLine += iStride;
68 }
69 nTotWeight = 256 - nTotWeight;
70 nSum += iCenterSample * nTotWeight;
71 aSample[i] = nSum >> 8;
72 pSample++;
73 }
74 WelsMemcpy (pSample - 8, aSample, 8);
75 }
76
77
78 /***************************************************************************
79 5x5 filter:
80 1 1 2 1 1
81 1 2 4 2 1
82 2 4 20 4 2
83 1 2 4 2 1
84 1 1 2 1 1
85 ***************************************************************************/
86 #define SUM_LINE1(pSample) (pSample[0] +(pSample[1]) +(pSample[2]<<1) + pSample[3] + pSample[4])
87 #define SUM_LINE2(pSample) (pSample[0] +(pSample[1]<<1) +(pSample[2]<<2) +(pSample[3]<<1) + pSample[4])
88 #define SUM_LINE3(pSample) ((pSample[0]<<1) +(pSample[1]<<2) +(pSample[2]*20) +(pSample[3]<<2) +(pSample[4]<<1))
WaverageChromaFilter8_c(uint8_t * pSample,int32_t iStride)89 void WaverageChromaFilter8_c (uint8_t* pSample, int32_t iStride) {
90 int32_t sum;
91 uint8_t* pStartPixels = pSample - UV_WINDOWS_RADIUS * iStride - UV_WINDOWS_RADIUS;
92 uint8_t* pCurLine1 = pStartPixels;
93 uint8_t* pCurLine2 = pCurLine1 + iStride;
94 uint8_t* pCurLine3 = pCurLine2 + iStride;
95 uint8_t* pCurLine4 = pCurLine3 + iStride;
96 uint8_t* pCurLine5 = pCurLine4 + iStride;
97 uint8_t aSample[8];
98
99 for (int32_t i = 0; i < 8; i++) {
100 sum = SUM_LINE1 ((pCurLine1 + i)) + SUM_LINE2 ((pCurLine2 + i)) + SUM_LINE3 ((pCurLine3 + i))
101 + SUM_LINE2 ((pCurLine4 + i)) + SUM_LINE1 ((pCurLine5 + i));
102 aSample[i] = (sum >> 6);
103 pSample++;
104 }
105 WelsMemcpy (pSample - 8, aSample, 8);
106 }
107
108 /***************************************************************************
109 edge of y/uv use a 3x3 Gauss filter, radius = 1:
110 1 2 1
111 2 4 2
112 1 2 1
113 ***************************************************************************/
Gauss3x3Filter(uint8_t * pSrc,int32_t iStride)114 void Gauss3x3Filter (uint8_t* pSrc, int32_t iStride) {
115 int32_t nSum = 0;
116 uint8_t* pCurLine1 = pSrc - iStride - 1;
117 uint8_t* pCurLine2 = pCurLine1 + iStride;
118 uint8_t* pCurLine3 = pCurLine2 + iStride;
119
120 nSum = pCurLine1[0] + (pCurLine1[1] << 1) + pCurLine1[2] +
121 (pCurLine2[0] << 1) + (pCurLine2[1] << 2) + (pCurLine2[2] << 1) +
122 pCurLine3[0] + (pCurLine3[1] << 1) + pCurLine3[2];
123 *pSrc = nSum >> 4;
124 }
125
126 WELSVP_NAMESPACE_END
127