Parent Directory
|
Revision Log
Revision 1.4 - (view) (download)
1 : | edgomez | 1.2 | /***************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC | ||
4 : | * Reduced-Resolution utilities | ||
5 : | * | ||
6 : | * Copyright(C) 2002 Pascal Massimino <skal@planet-d.net> | ||
7 : | * | ||
8 : | * XviD is free software; you can redistribute it and/or modify it | ||
9 : | * under the terms of the GNU General Public License as published by | ||
10 : | * the Free Software Foundation; either version 2 of the License, or | ||
11 : | * (at your option) any later version. | ||
12 : | * | ||
13 : | * This program is distributed in the hope that it will be useful, | ||
14 : | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 : | * GNU General Public License for more details. | ||
17 : | * | ||
18 : | * You should have received a copy of the GNU General Public License | ||
19 : | * along with this program; if not, write to the Free Software | ||
20 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 : | * | ||
22 : | edgomez | 1.3 | * $Id$ |
23 : | edgomez | 1.2 | * |
24 : | ****************************************************************************/ | ||
25 : | |||
26 : | #include "../portab.h" | ||
27 : | #include "../global.h" | ||
28 : | #include "reduced.h" | ||
29 : | |||
30 : | edgomez | 1.3 | /* function pointers */ |
31 : | edgomez | 1.2 | COPY_UPSAMPLED_8X8_16TO8 * copy_upsampled_8x8_16to8; |
32 : | ADD_UPSAMPLED_8X8_16TO8 * add_upsampled_8x8_16to8; | ||
33 : | VFILTER_31 * vfilter_31; | ||
34 : | HFILTER_31 * hfilter_31; | ||
35 : | FILTER_18X18_TO_8X8 * filter_18x18_to_8x8; | ||
36 : | FILTER_DIFF_18X18_TO_8X8 * filter_diff_18x18_to_8x8; | ||
37 : | |||
38 : | edgomez | 1.3 | /*---------------------------------------------------------------------------- |
39 : | * Upsampling (1/3/3/1) filter | ||
40 : | *--------------------------------------------------------------------------*/ | ||
41 : | edgomez | 1.2 | |
42 : | #define ADD(dst,src) (dst) = CLIP((dst)+(src), 0, 255) | ||
43 : | |||
44 : | static __inline void Filter_31(uint8_t *Dst1, uint8_t *Dst2, | ||
45 : | const int16_t *Src1, const int16_t *Src2) | ||
46 : | { | ||
47 : | /* Src[] is assumed to be >=0. So we can use ">>2" instead of "/2" */ | ||
48 : | int16_t a = (3*Src1[0]+ Src2[0]+2) >> 2; | ||
49 : | int16_t b = ( Src1[0]+3*Src2[0]+2) >> 2; | ||
50 : | Dst1[0] = CLIP(a, 0, 255); | ||
51 : | Dst2[0] = CLIP(b, 0, 255); | ||
52 : | } | ||
53 : | |||
54 : | static __inline void Filter_9331(uint8_t *Dst1, uint8_t *Dst2, | ||
55 : | const int16_t *Src1, const int16_t *Src2) | ||
56 : | { | ||
57 : | /* Src[] is assumed to be >=0. So we can use ">>4" instead of "/16" */ | ||
58 : | int16_t a = (9*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 1*Src2[1] + 8) >> 4; | ||
59 : | int16_t b = (3*Src1[0]+ 9*Src1[1]+ 1*Src2[0] + 3*Src2[1] + 8) >> 4; | ||
60 : | int16_t c = (3*Src1[0]+ 1*Src1[1]+ 9*Src2[0] + 3*Src2[1] + 8) >> 4; | ||
61 : | int16_t d = (1*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 9*Src2[1] + 8) >> 4; | ||
62 : | Dst1[0] = CLIP(a, 0, 255); | ||
63 : | Dst1[1] = CLIP(b, 0, 255); | ||
64 : | Dst2[0] = CLIP(c, 0, 255); | ||
65 : | Dst2[1] = CLIP(d, 0, 255); | ||
66 : | } | ||
67 : | |||
68 : | void xvid_Copy_Upsampled_8x8_16To8_C(uint8_t *Dst, const int16_t *Src, const int BpS) | ||
69 : | { | ||
70 : | int x, y; | ||
71 : | |||
72 : | Dst[0] = CLIP(Src[0], 0, 255); | ||
73 : | for(x=0; x<7; ++x) Filter_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); | ||
74 : | Dst[15] = CLIP(Src[7], 0, 255); | ||
75 : | Dst += BpS; | ||
76 : | for(y=0; y<7; ++y) { | ||
77 : | uint8_t *const Dst2 = Dst + BpS; | ||
78 : | Filter_31(Dst, Dst2, Src, Src+8); | ||
79 : | for(x=0; x<7; ++x) | ||
80 : | Filter_9331(Dst+2*x+1, Dst2+2*x+1, Src+x, Src+x+8); | ||
81 : | Filter_31(Dst+15, Dst2+15, Src+7, Src+7+8); | ||
82 : | edgomez | 1.3 | Src += 8; |
83 : | edgomez | 1.2 | Dst += 2*BpS; |
84 : | } | ||
85 : | Dst[0] = CLIP(Src[0], 0, 255); | ||
86 : | for(x=0; x<7; ++x) Filter_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); | ||
87 : | Dst[15] = CLIP(Src[7], 0, 255); | ||
88 : | } | ||
89 : | |||
90 : | static __inline void Filter_Add_31(uint8_t *Dst1, uint8_t *Dst2, | ||
91 : | const int16_t *Src1, const int16_t *Src2) | ||
92 : | { | ||
93 : | /* Here, we must use "/4", since Src[] is in [-256, 255] */ | ||
94 : | int16_t a = (3*Src1[0]+ Src2[0] + 2) / 4; | ||
95 : | int16_t b = ( Src1[0]+3*Src2[0] + 2) / 4; | ||
96 : | ADD(Dst1[0], a); | ||
97 : | ADD(Dst2[0], b); | ||
98 : | } | ||
99 : | |||
100 : | static __inline void Filter_Add_9331(uint8_t *Dst1, uint8_t *Dst2, | ||
101 : | const int16_t *Src1, const int16_t *Src2) | ||
102 : | { | ||
103 : | int16_t a = (9*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 1*Src2[1] + 8) / 16; | ||
104 : | int16_t b = (3*Src1[0]+ 9*Src1[1]+ 1*Src2[0] + 3*Src2[1] + 8) / 16; | ||
105 : | int16_t c = (3*Src1[0]+ 1*Src1[1]+ 9*Src2[0] + 3*Src2[1] + 8) / 16; | ||
106 : | int16_t d = (1*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 9*Src2[1] + 8) / 16; | ||
107 : | ADD(Dst1[0], a); | ||
108 : | ADD(Dst1[1], b); | ||
109 : | ADD(Dst2[0], c); | ||
110 : | ADD(Dst2[1], d); | ||
111 : | } | ||
112 : | |||
113 : | void xvid_Add_Upsampled_8x8_16To8_C(uint8_t *Dst, const int16_t *Src, const int BpS) | ||
114 : | { | ||
115 : | int x, y; | ||
116 : | |||
117 : | ADD(Dst[0], Src[0]); | ||
118 : | for(x=0; x<7; ++x) Filter_Add_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); | ||
119 : | ADD(Dst[15], Src[7]); | ||
120 : | Dst += BpS; | ||
121 : | for(y=0; y<7; ++y) { | ||
122 : | uint8_t *const Dst2 = Dst + BpS; | ||
123 : | Filter_Add_31(Dst, Dst2, Src, Src+8); | ||
124 : | for(x=0; x<7; ++x) | ||
125 : | Filter_Add_9331(Dst+2*x+1, Dst2+2*x+1, Src+x, Src+x+8); | ||
126 : | Filter_Add_31(Dst+15, Dst2+15, Src+7, Src+7+8); | ||
127 : | edgomez | 1.3 | Src += 8; |
128 : | edgomez | 1.2 | Dst += 2*BpS; |
129 : | } | ||
130 : | ADD(Dst[0], Src[0]); | ||
131 : | for(x=0; x<7; ++x) Filter_Add_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); | ||
132 : | ADD(Dst[15], Src[7]); | ||
133 : | } | ||
134 : | #undef ADD | ||
135 : | |||
136 : | edgomez | 1.3 | /*---------------------------------------------------------------------------- |
137 : | * horizontal and vertical deblocking | ||
138 : | *--------------------------------------------------------------------------*/ | ||
139 : | edgomez | 1.2 | |
140 : | void xvid_HFilter_31_C(uint8_t *Src1, uint8_t *Src2, int Nb_Blks) | ||
141 : | { | ||
142 : | Nb_Blks *= 8; | ||
143 : | while(Nb_Blks-->0) { | ||
144 : | uint8_t a = ( 3*Src1[0] + 1*Src2[0] + 2 ) >> 2; | ||
145 : | uint8_t b = ( 1*Src1[0] + 3*Src2[0] + 2 ) >> 2; | ||
146 : | *Src1++ = a; | ||
147 : | *Src2++ = b; | ||
148 : | } | ||
149 : | } | ||
150 : | |||
151 : | void xvid_VFilter_31_C(uint8_t *Src1, uint8_t *Src2, const int BpS, int Nb_Blks) | ||
152 : | { | ||
153 : | Nb_Blks *= 8; | ||
154 : | while(Nb_Blks-->0) { | ||
155 : | uint8_t a = ( 3*Src1[0] + 1*Src2[0] + 2 ) >> 2; | ||
156 : | uint8_t b = ( 1*Src1[0] + 3*Src2[0] + 2 ) >> 2; | ||
157 : | *Src1 = a; | ||
158 : | *Src2 = b; | ||
159 : | Src1 += BpS; | ||
160 : | Src2 += BpS; | ||
161 : | } | ||
162 : | } | ||
163 : | |||
164 : | edgomez | 1.3 | /*---------------------------------------------------------------------------- |
165 : | * 16x16 -> 8x8 (1/3/3/1) downsampling | ||
166 : | * | ||
167 : | * Warning! These read 1 pixel outside of the input 16x16 block! | ||
168 : | *--------------------------------------------------------------------------*/ | ||
169 : | edgomez | 1.2 | |
170 : | void xvid_Filter_18x18_To_8x8_C(int16_t *Dst, const uint8_t *Src, const int BpS) | ||
171 : | { | ||
172 : | int16_t *T, Tmp[18*8]; | ||
173 : | int i, j; | ||
174 : | |||
175 : | T = Tmp; | ||
176 : | Src -= BpS; | ||
177 : | for(j=-1; j<17; j++) { | ||
178 : | for(i=0; i<8; ++i) | ||
179 : | T[i] = Src[2*i-1] + 3*Src[2*i+0] + 3*Src[2*i+1] + Src[2*i+2]; | ||
180 : | T += 8; | ||
181 : | Src += BpS; | ||
182 : | } | ||
183 : | T = Tmp + 8; | ||
184 : | for(j=0; j<8; j++) { | ||
185 : | for(i=0; i<8; ++i) | ||
186 : | Dst[i] = ( T[-8+i] + 3*T[0+i] + 3*T[8+i] + T[16+i] + 32 ) / 64; | ||
187 : | Dst += 8; | ||
188 : | T += 16; | ||
189 : | } | ||
190 : | } | ||
191 : | |||
192 : | void xvid_Filter_Diff_18x18_To_8x8_C(int16_t *Dst, const uint8_t *Src, const int BpS) | ||
193 : | { | ||
194 : | int16_t *T, Tmp[18*8]; | ||
195 : | int i, j; | ||
196 : | |||
197 : | T = Tmp; | ||
198 : | Src -= BpS; | ||
199 : | for(j=-1; j<17; j++) { | ||
200 : | for(i=0; i<8; ++i) | ||
201 : | T[i] = Src[2*i-1] + 3*Src[2*i+0] + 3*Src[2*i+1] + Src[2*i+2]; | ||
202 : | T += 8; | ||
203 : | Src += BpS; | ||
204 : | } | ||
205 : | T = Tmp; | ||
206 : | for(j=0; j<8; j++) { | ||
207 : | for(i=0; i<8; ++i) | ||
208 : | Dst[i] -= ( T[i] + 3*T[8+i] + 3*T[16+i] + T[24+i] + 32 ) / 64; | ||
209 : | Dst += 8; | ||
210 : | T += 16; | ||
211 : | } | ||
212 : | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |