1 /*****************************************************************************
2  *
3  *  XVID MPEG-4 VIDEO CODEC
4  *  - 8bit<->16bit transfer  -
5  *
6  *  Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7  *
8  *  This program is free software ; you can redistribute it and/or modify
9  *  it 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  * $Id: mem_transfer.c 1985 2011-05-18 09:02:35Z Isibaar $
23  *
24  ****************************************************************************/
25 
26 #include "../global.h"
27 #include "mem_transfer.h"
28 
29 /* Function pointers - Initialized in the xvid.c module */
30 
31 TRANSFER_8TO16COPY_PTR transfer_8to16copy;
32 TRANSFER_16TO8COPY_PTR transfer_16to8copy;
33 
34 TRANSFER_8TO16SUB_PTR  transfer_8to16sub;
35 TRANSFER_8TO16SUBRO_PTR  transfer_8to16subro;
36 TRANSFER_8TO16SUB2_PTR transfer_8to16sub2;
37 TRANSFER_8TO16SUB2RO_PTR transfer_8to16sub2ro;
38 TRANSFER_16TO8ADD_PTR  transfer_16to8add;
39 
40 TRANSFER8X8_COPY_PTR transfer8x8_copy;
41 TRANSFER8X4_COPY_PTR transfer8x4_copy;
42 
43 #define USE_REFERENCE_C
44 
45 /*****************************************************************************
46  *
47  * All these functions are used to transfer data from a 8 bit data array
48  * to a 16 bit data array.
49  *
50  * This is typically used during motion compensation, that's why some
51  * functions also do the addition/substraction of another buffer during the
52  * so called  transfer.
53  *
54  ****************************************************************************/
55 
56 /*
57  * SRC - the source buffer
58  * DST - the destination buffer
59  *
60  * Then the function does the 8->16 bit transfer and this serie of operations :
61  *
62  *    SRC (8bit)  = SRC
63  *    DST (16bit) = SRC
64  */
65 void
transfer_8to16copy_c(int16_t * const dst,const uint8_t * const src,uint32_t stride)66 transfer_8to16copy_c(int16_t * const dst,
67 					 const uint8_t * const src,
68 					 uint32_t stride)
69 {
70 	int i, j;
71 	for (j = 0; j < 8; j++) {
72 		for (i = 0; i < 8; i++) {
73 			dst[j * 8 + i] = (int16_t) src[j * stride + i];
74 		}
75 	}
76 }
77 
78 /*
79  * SRC - the source buffer
80  * DST - the destination buffer
81  *
82  * Then the function does the 8->16 bit transfer and this serie of operations :
83  *
84  *    SRC (16bit) = SRC
85  *    DST (8bit)  = max(min(SRC, 255), 0)
86  */
87 void
transfer_16to8copy_c(uint8_t * const dst,const int16_t * const src,uint32_t stride)88 transfer_16to8copy_c(uint8_t * const dst,
89 					 const int16_t * const src,
90 					 uint32_t stride)
91 {
92 	int i, j;
93 
94 	for (j = 0; j < 8; j++) {
95 		for (i = 0; i < 8; i++) {
96 #ifdef USE_REFERENCE_C
97 			int16_t pixel = src[j * 8 + i];
98 
99 			if (pixel < 0) {
100 				pixel = 0;
101 			} else if (pixel > 255) {
102 				pixel = 255;
103 			}
104 			dst[j * stride + i] = (uint8_t) pixel;
105 #else
106 			const int16_t pixel = src[j * 8 + i];
107 			const uint8_t value = (uint8_t)( (pixel&~255) ? (-pixel)>>(8*sizeof(pixel)-1) : pixel );
108 			dst[j*stride + i] = value;
109 #endif
110     }
111 	}
112 }
113 
114 
115 
116 
117 /*
118  * C   - the current buffer
119  * R   - the reference buffer
120  * DCT - the dct coefficient buffer
121  *
122  * Then the function does the 8->16 bit transfer and this serie of operations :
123  *
124  *    R   (8bit)  = R
125  *    C   (8bit)  = R
126  *    DCT (16bit) = C - R
127  */
128 void
transfer_8to16sub_c(int16_t * const dct,uint8_t * const cur,const uint8_t * ref,const uint32_t stride)129 transfer_8to16sub_c(int16_t * const dct,
130 					uint8_t * const cur,
131 					const uint8_t * ref,
132 					const uint32_t stride)
133 {
134 	int i, j;
135 
136 	for (j = 0; j < 8; j++) {
137 		for (i = 0; i < 8; i++) {
138 			const uint8_t c = cur[j * stride + i];
139 			const uint8_t r = ref[j * stride + i];
140 
141 			cur[j * stride + i] = r;
142 			dct[j * 8 + i] = (int16_t) c - (int16_t) r;
143 		}
144 	}
145 }
146 
147 
148 void
transfer_8to16subro_c(int16_t * const dct,const uint8_t * const cur,const uint8_t * ref,const uint32_t stride)149 transfer_8to16subro_c(int16_t * const dct,
150 					const uint8_t * const cur,
151 					const uint8_t * ref,
152 					const uint32_t stride)
153 {
154 	int i, j;
155 
156 	for (j = 0; j < 8; j++) {
157 		for (i = 0; i < 8; i++) {
158 			const uint8_t c = cur[j * stride + i];
159 			const uint8_t r = ref[j * stride + i];
160 			dct[j * 8 + i] = (int16_t) c - (int16_t) r;
161 		}
162 	}
163 }
164 
165 
166 
167 /*
168  * C   - the current buffer
169  * R1  - the 1st reference buffer
170  * R2  - the 2nd reference buffer
171  * DCT - the dct coefficient buffer
172  *
173  * Then the function does the 8->16 bit transfer and this serie of operations :
174  *
175  *    R1  (8bit) = R1
176  *    R2  (8bit) = R2
177  *    R   (temp) = min((R1 + R2)/2, 255)
178  *    DCT (16bit)= C - R
179  *    C   (8bit) = R
180  */
181 void
transfer_8to16sub2_c(int16_t * const dct,uint8_t * const cur,const uint8_t * ref1,const uint8_t * ref2,const uint32_t stride)182 transfer_8to16sub2_c(int16_t * const dct,
183 					 uint8_t * const cur,
184 					 const uint8_t * ref1,
185 					 const uint8_t * ref2,
186 					 const uint32_t stride)
187 {
188 	uint32_t i, j;
189 
190 	for (j = 0; j < 8; j++) {
191 		for (i = 0; i < 8; i++) {
192 			const uint8_t c = cur[j * stride + i];
193 			const uint8_t r = (ref1[j * stride + i] + ref2[j * stride + i] + 1) >> 1;
194 			cur[j * stride + i] = r;
195 			dct[j * 8 + i] = (int16_t) c - (int16_t) r;
196 		}
197 	}
198 }
199 
200 void
transfer_8to16sub2ro_c(int16_t * const dct,const uint8_t * const cur,const uint8_t * ref1,const uint8_t * ref2,const uint32_t stride)201 transfer_8to16sub2ro_c(int16_t * const dct,
202 					 const uint8_t * const cur,
203 					 const uint8_t * ref1,
204 					 const uint8_t * ref2,
205 					 const uint32_t stride)
206 {
207 	uint32_t i, j;
208 
209 	for (j = 0; j < 8; j++) {
210 		for (i = 0; i < 8; i++) {
211 			const uint8_t c = cur[j * stride + i];
212 			const uint8_t r = (ref1[j * stride + i] + ref2[j * stride + i] + 1) >> 1;
213 			dct[j * 8 + i] = (int16_t) c - (int16_t) r;
214 		}
215 	}
216 }
217 
218 
219 /*
220  * SRC - the source buffer
221  * DST - the destination buffer
222  *
223  * Then the function does the 16->8 bit transfer and this serie of operations :
224  *
225  *    SRC (16bit) = SRC
226  *    DST (8bit)  = max(min(DST+SRC, 255), 0)
227  */
228 void
transfer_16to8add_c(uint8_t * const dst,const int16_t * const src,uint32_t stride)229 transfer_16to8add_c(uint8_t * const dst,
230 					const int16_t * const src,
231 					uint32_t stride)
232 {
233 	int i, j;
234 
235 	for (j = 0; j < 8; j++) {
236 		for (i = 0; i < 8; i++) {
237 #ifdef USE_REFERENCE_C
238 			int16_t pixel = (int16_t) dst[j * stride + i] + src[j * 8 + i];
239 
240 			if (pixel < 0) {
241 				pixel = 0;
242 			} else if (pixel > 255) {
243 				pixel = 255;
244 			}
245 			dst[j * stride + i] = (uint8_t) pixel;
246 #else
247       const int16_t pixel = (int16_t) dst[j * stride + i] + src[j * 8 + i];
248 			const uint8_t value = (uint8_t)( (pixel&~255) ? (-pixel)>>(8*sizeof(pixel)-1) : pixel );
249 			dst[j*stride + i] = value;
250 #endif
251 
252 		}
253 	}
254 }
255 
256 /*
257  * SRC - the source buffer
258  * DST - the destination buffer
259  *
260  * Then the function does the 8->8 bit transfer and this serie of operations :
261  *
262  *    SRC (8bit) = SRC
263  *    DST (8bit) = SRC
264  */
265 void
transfer8x8_copy_c(uint8_t * const dst,const uint8_t * const src,const uint32_t stride)266 transfer8x8_copy_c(uint8_t * const dst,
267 				   const uint8_t * const src,
268 				   const uint32_t stride)
269 {
270 	int j, i;
271 
272 	for (j = 0; j < 8; ++j) {
273 	    uint8_t *d = dst + j*stride;
274 		const uint8_t *s = src + j*stride;
275 
276 		for (i = 0; i < 8; ++i)
277 		{
278 			*d++ = *s++;
279 		}
280 	}
281 }
282 
283 /*
284  * SRC - the source buffer
285  * DST - the destination buffer
286  *
287  * Then the function does the 8->8 bit transfer and this serie of operations :
288  *
289  *    SRC (8bit) = SRC
290  *    DST (8bit) = SRC
291  */
292 void
transfer8x4_copy_c(uint8_t * const dst,const uint8_t * const src,const uint32_t stride)293 transfer8x4_copy_c(uint8_t * const dst,
294 				   const uint8_t * const src,
295 				   const uint32_t stride)
296 {
297 	uint32_t j;
298 
299 	for (j = 0; j < 4; j++) {
300 		uint32_t *d= (uint32_t*)(dst + j*stride);
301 		const uint32_t *s = (const uint32_t*)(src + j*stride);
302 		*(d+0) = *(s+0);
303 		*(d+1) = *(s+1);
304 	}
305 }
306