make some global var static (fix a build failure with shared lib on x86_64)
[ffmpeg.git] / libswscale / swscale_template.c
1 /*
2     Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18     the C code (not assembly, mmx, ...) of the swscaler which has been written
19     by Michael Niedermayer can be used under the LGPL license too
20 */
21
22 #undef REAL_MOVNTQ
23 #undef MOVNTQ
24 #undef PAVGB
25 #undef PREFETCH
26 #undef PREFETCHW
27 #undef EMMS
28 #undef SFENCE
29
30 #ifdef HAVE_3DNOW
31 /* On K6 femms is faster of emms. On K7 femms is directly mapped on emms. */
32 #define EMMS     "femms"
33 #else
34 #define EMMS     "emms"
35 #endif
36
37 #ifdef HAVE_3DNOW
38 #define PREFETCH  "prefetch"
39 #define PREFETCHW "prefetchw"
40 #elif defined ( HAVE_MMX2 )
41 #define PREFETCH "prefetchnta"
42 #define PREFETCHW "prefetcht0"
43 #else
44 #define PREFETCH "/nop"
45 #define PREFETCHW "/nop"
46 #endif
47
48 #ifdef HAVE_MMX2
49 #define SFENCE "sfence"
50 #else
51 #define SFENCE "/nop"
52 #endif
53
54 #ifdef HAVE_MMX2
55 #define PAVGB(a,b) "pavgb " #a ", " #b " \n\t"
56 #elif defined (HAVE_3DNOW)
57 #define PAVGB(a,b) "pavgusb " #a ", " #b " \n\t"
58 #endif
59
60 #ifdef HAVE_MMX2
61 #define REAL_MOVNTQ(a,b) "movntq " #a ", " #b " \n\t"
62 #else
63 #define REAL_MOVNTQ(a,b) "movq " #a ", " #b " \n\t"
64 #endif
65 #define MOVNTQ(a,b)  REAL_MOVNTQ(a,b)
66
67 #ifdef HAVE_ALTIVEC
68 #include "swscale_altivec_template.c"
69 #endif
70
71 #define YSCALEYUV2YV12X(x, offset, dest, width) \
72                 asm volatile(\
73                         "xor %%"REG_a", %%"REG_a"       \n\t"\
74                         "movq "VROUNDER_OFFSET"(%0), %%mm3\n\t"\
75                         "movq %%mm3, %%mm4              \n\t"\
76                         "lea " offset "(%0), %%"REG_d"  \n\t"\
77                         "mov (%%"REG_d"), %%"REG_S"     \n\t"\
78                         ASMALIGN(4) /* FIXME Unroll? */\
79                         "1:                             \n\t"\
80                         "movq 8(%%"REG_d"), %%mm0       \n\t" /* filterCoeff */\
81                         "movq " #x "(%%"REG_S", %%"REG_a", 2), %%mm2\n\t" /* srcData */\
82                         "movq 8+" #x "(%%"REG_S", %%"REG_a", 2), %%mm5\n\t" /* srcData */\
83                         "add $16, %%"REG_d"             \n\t"\
84                         "mov (%%"REG_d"), %%"REG_S"     \n\t"\
85                         "test %%"REG_S", %%"REG_S"      \n\t"\
86                         "pmulhw %%mm0, %%mm2            \n\t"\
87                         "pmulhw %%mm0, %%mm5            \n\t"\
88                         "paddw %%mm2, %%mm3             \n\t"\
89                         "paddw %%mm5, %%mm4             \n\t"\
90                         " jnz 1b                        \n\t"\
91                         "psraw $3, %%mm3                \n\t"\
92                         "psraw $3, %%mm4                \n\t"\
93                         "packuswb %%mm4, %%mm3          \n\t"\
94                         MOVNTQ(%%mm3, (%1, %%REGa))\
95                         "add $8, %%"REG_a"              \n\t"\
96                         "cmp %2, %%"REG_a"              \n\t"\
97                         "movq "VROUNDER_OFFSET"(%0), %%mm3\n\t"\
98                         "movq %%mm3, %%mm4              \n\t"\
99                         "lea " offset "(%0), %%"REG_d"  \n\t"\
100                         "mov (%%"REG_d"), %%"REG_S"     \n\t"\
101                         "jb 1b                          \n\t"\
102                         :: "r" (&c->redDither),\
103                         "r" (dest), "p" (width)\
104                         : "%"REG_a, "%"REG_d, "%"REG_S\
105                 );
106
107 #define YSCALEYUV2YV12X_ACCURATE(x, offset, dest, width) \
108                 asm volatile(\
109                         "lea " offset "(%0), %%"REG_d"  \n\t"\
110                         "xor %%"REG_a", %%"REG_a"       \n\t"\
111                         "pxor %%mm4, %%mm4              \n\t"\
112                         "pxor %%mm5, %%mm5              \n\t"\
113                         "pxor %%mm6, %%mm6              \n\t"\
114                         "pxor %%mm7, %%mm7              \n\t"\
115                         "mov (%%"REG_d"), %%"REG_S"     \n\t"\
116                         ASMALIGN(4) \
117                         "1:                             \n\t"\
118                         "movq " #x "(%%"REG_S", %%"REG_a", 2), %%mm0\n\t" /* srcData */\
119                         "movq 8+" #x "(%%"REG_S", %%"REG_a", 2), %%mm2\n\t" /* srcData */\
120                         "mov 4(%%"REG_d"), %%"REG_S"    \n\t"\
121                         "movq " #x "(%%"REG_S", %%"REG_a", 2), %%mm1\n\t" /* srcData */\
122                         "movq %%mm0, %%mm3              \n\t"\
123                         "punpcklwd %%mm1, %%mm0        \n\t"\
124                         "punpckhwd %%mm1, %%mm3        \n\t"\
125                         "movq 8(%%"REG_d"), %%mm1       \n\t" /* filterCoeff */\
126                         "pmaddwd %%mm1, %%mm0           \n\t"\
127                         "pmaddwd %%mm1, %%mm3           \n\t"\
128                         "paddd %%mm0, %%mm4             \n\t"\
129                         "paddd %%mm3, %%mm5             \n\t"\
130                         "movq 8+" #x "(%%"REG_S", %%"REG_a", 2), %%mm3\n\t" /* srcData */\
131                         "mov 16(%%"REG_d"), %%"REG_S"   \n\t"\
132                         "add $16, %%"REG_d"             \n\t"\
133                         "test %%"REG_S", %%"REG_S"      \n\t"\
134                         "movq %%mm2, %%mm0              \n\t"\
135                         "punpcklwd %%mm3, %%mm2        \n\t"\
136                         "punpckhwd %%mm3, %%mm0        \n\t"\
137                         "pmaddwd %%mm1, %%mm2           \n\t"\
138                         "pmaddwd %%mm1, %%mm0           \n\t"\
139                         "paddd %%mm2, %%mm6             \n\t"\
140                         "paddd %%mm0, %%mm7             \n\t"\
141                         " jnz 1b                        \n\t"\
142                         "psrad $16, %%mm4               \n\t"\
143                         "psrad $16, %%mm5               \n\t"\
144                         "psrad $16, %%mm6               \n\t"\
145                         "psrad $16, %%mm7               \n\t"\
146                         "movq "VROUNDER_OFFSET"(%0), %%mm0\n\t"\
147                         "packssdw %%mm5, %%mm4          \n\t"\
148                         "packssdw %%mm7, %%mm6          \n\t"\
149                         "paddw %%mm0, %%mm4             \n\t"\
150                         "paddw %%mm0, %%mm6             \n\t"\
151                         "psraw $3, %%mm4                \n\t"\
152                         "psraw $3, %%mm6                \n\t"\
153                         "packuswb %%mm6, %%mm4          \n\t"\
154                         MOVNTQ(%%mm4, (%1, %%REGa))\
155                         "add $8, %%"REG_a"              \n\t"\
156                         "cmp %2, %%"REG_a"              \n\t"\
157                         "lea " offset "(%0), %%"REG_d"  \n\t"\
158                         "pxor %%mm4, %%mm4              \n\t"\
159                         "pxor %%mm5, %%mm5              \n\t"\
160                         "pxor %%mm6, %%mm6              \n\t"\
161                         "pxor %%mm7, %%mm7              \n\t"\
162                         "mov (%%"REG_d"), %%"REG_S"     \n\t"\
163                         "jb 1b                          \n\t"\
164                         :: "r" (&c->redDither),\
165                         "r" (dest), "p" (width)\
166                         : "%"REG_a, "%"REG_d, "%"REG_S\
167                 );
168
169 #define YSCALEYUV2YV121 \
170                         "mov %2, %%"REG_a"              \n\t"\
171                         ASMALIGN(4) /* FIXME Unroll? */\
172                         "1:                             \n\t"\
173                         "movq (%0, %%"REG_a", 2), %%mm0 \n\t"\
174                         "movq 8(%0, %%"REG_a", 2), %%mm1\n\t"\
175                         "psraw $7, %%mm0                \n\t"\
176                         "psraw $7, %%mm1                \n\t"\
177                         "packuswb %%mm1, %%mm0          \n\t"\
178                         MOVNTQ(%%mm0, (%1, %%REGa))\
179                         "add $8, %%"REG_a"              \n\t"\
180                         "jnc 1b                         \n\t"
181
182 /*
183                         :: "m" (-lumFilterSize), "m" (-chrFilterSize),
184                            "m" (lumMmxFilter+lumFilterSize*4), "m" (chrMmxFilter+chrFilterSize*4),
185                            "r" (dest), "m" (dstW),
186                            "m" (lumSrc+lumFilterSize), "m" (chrSrc+chrFilterSize)
187                         : "%eax", "%ebx", "%ecx", "%edx", "%esi"
188 */
189 #define YSCALEYUV2PACKEDX \
190         asm volatile(\
191                 "xor %%"REG_a", %%"REG_a"       \n\t"\
192                 ASMALIGN(4)\
193                 "nop                            \n\t"\
194                 "1:                             \n\t"\
195                 "lea "CHR_MMX_FILTER_OFFSET"(%0), %%"REG_d"\n\t"\
196                 "mov (%%"REG_d"), %%"REG_S"     \n\t"\
197                 "movq "VROUNDER_OFFSET"(%0), %%mm3\n\t"\
198                 "movq %%mm3, %%mm4              \n\t"\
199                 ASMALIGN(4)\
200                 "2:                             \n\t"\
201                 "movq 8(%%"REG_d"), %%mm0       \n\t" /* filterCoeff */\
202                 "movq (%%"REG_S", %%"REG_a"), %%mm2     \n\t" /* UsrcData */\
203                 "movq 4096(%%"REG_S", %%"REG_a"), %%mm5 \n\t" /* VsrcData */\
204                 "add $16, %%"REG_d"             \n\t"\
205                 "mov (%%"REG_d"), %%"REG_S"     \n\t"\
206                 "pmulhw %%mm0, %%mm2            \n\t"\
207                 "pmulhw %%mm0, %%mm5            \n\t"\
208                 "paddw %%mm2, %%mm3             \n\t"\
209                 "paddw %%mm5, %%mm4             \n\t"\
210                 "test %%"REG_S", %%"REG_S"      \n\t"\
211                 " jnz 2b                        \n\t"\
212 \
213                 "lea "LUM_MMX_FILTER_OFFSET"(%0), %%"REG_d"\n\t"\
214                 "mov (%%"REG_d"), %%"REG_S"     \n\t"\
215                 "movq "VROUNDER_OFFSET"(%0), %%mm1\n\t"\
216                 "movq %%mm1, %%mm7              \n\t"\
217                 ASMALIGN(4)\
218                 "2:                             \n\t"\
219                 "movq 8(%%"REG_d"), %%mm0       \n\t" /* filterCoeff */\
220                 "movq (%%"REG_S", %%"REG_a", 2), %%mm2  \n\t" /* Y1srcData */\
221                 "movq 8(%%"REG_S", %%"REG_a", 2), %%mm5 \n\t" /* Y2srcData */\
222                 "add $16, %%"REG_d"             \n\t"\
223                 "mov (%%"REG_d"), %%"REG_S"     \n\t"\
224                 "pmulhw %%mm0, %%mm2            \n\t"\
225                 "pmulhw %%mm0, %%mm5            \n\t"\
226                 "paddw %%mm2, %%mm1             \n\t"\
227                 "paddw %%mm5, %%mm7             \n\t"\
228                 "test %%"REG_S", %%"REG_S"      \n\t"\
229                 " jnz 2b                        \n\t"\
230
231 #define YSCALEYUV2PACKEDX_END\
232         :: "r" (&c->redDither), \
233             "m" (dummy), "m" (dummy), "m" (dummy),\
234             "r" (dest), "m" (dstW)\
235         : "%"REG_a, "%"REG_d, "%"REG_S\
236         );
237
238 #define YSCALEYUV2PACKEDX_ACCURATE \
239         asm volatile(\
240                 "xor %%"REG_a", %%"REG_a"       \n\t"\
241                 ASMALIGN(4)\
242                 "nop                            \n\t"\
243                 "1:                             \n\t"\
244                 "lea "CHR_MMX_FILTER_OFFSET"(%0), %%"REG_d"\n\t"\
245                 "mov (%%"REG_d"), %%"REG_S"     \n\t"\
246                 "pxor %%mm4, %%mm4              \n\t"\
247                 "pxor %%mm5, %%mm5              \n\t"\
248                 "pxor %%mm6, %%mm6              \n\t"\
249                 "pxor %%mm7, %%mm7              \n\t"\
250                 ASMALIGN(4)\
251                 "2:                             \n\t"\
252                 "movq (%%"REG_S", %%"REG_a"), %%mm0     \n\t" /* UsrcData */\
253                 "movq 4096(%%"REG_S", %%"REG_a"), %%mm2 \n\t" /* VsrcData */\
254                 "mov 4(%%"REG_d"), %%"REG_S"    \n\t"\
255                 "movq (%%"REG_S", %%"REG_a"), %%mm1     \n\t" /* UsrcData */\
256                 "movq %%mm0, %%mm3              \n\t"\
257                 "punpcklwd %%mm1, %%mm0        \n\t"\
258                 "punpckhwd %%mm1, %%mm3        \n\t"\
259                 "movq 8(%%"REG_d"), %%mm1       \n\t" /* filterCoeff */\
260                 "pmaddwd %%mm1, %%mm0           \n\t"\
261                 "pmaddwd %%mm1, %%mm3           \n\t"\
262                 "paddd %%mm0, %%mm4             \n\t"\
263                 "paddd %%mm3, %%mm5             \n\t"\
264                 "movq 4096(%%"REG_S", %%"REG_a"), %%mm3 \n\t" /* VsrcData */\
265                 "mov 16(%%"REG_d"), %%"REG_S"   \n\t"\
266                 "add $16, %%"REG_d"             \n\t"\
267                 "test %%"REG_S", %%"REG_S"      \n\t"\
268                 "movq %%mm2, %%mm0              \n\t"\
269                 "punpcklwd %%mm3, %%mm2        \n\t"\
270                 "punpckhwd %%mm3, %%mm0        \n\t"\
271                 "pmaddwd %%mm1, %%mm2           \n\t"\
272                 "pmaddwd %%mm1, %%mm0           \n\t"\
273                 "paddd %%mm2, %%mm6             \n\t"\
274                 "paddd %%mm0, %%mm7             \n\t"\
275                 " jnz 2b                        \n\t"\
276                 "psrad $16, %%mm4               \n\t"\
277                 "psrad $16, %%mm5               \n\t"\
278                 "psrad $16, %%mm6               \n\t"\
279                 "psrad $16, %%mm7               \n\t"\
280                 "movq "VROUNDER_OFFSET"(%0), %%mm0\n\t"\
281                 "packssdw %%mm5, %%mm4          \n\t"\
282                 "packssdw %%mm7, %%mm6          \n\t"\
283                 "paddw %%mm0, %%mm4             \n\t"\
284                 "paddw %%mm0, %%mm6             \n\t"\
285                 "movq %%mm4, "U_TEMP"(%0)       \n\t"\
286                 "movq %%mm6, "V_TEMP"(%0)       \n\t"\
287 \
288                 "lea "LUM_MMX_FILTER_OFFSET"(%0), %%"REG_d"\n\t"\
289                 "mov (%%"REG_d"), %%"REG_S"     \n\t"\
290                 "pxor %%mm1, %%mm1              \n\t"\
291                 "pxor %%mm5, %%mm5              \n\t"\
292                 "pxor %%mm7, %%mm7              \n\t"\
293                 "pxor %%mm6, %%mm6              \n\t"\
294                 ASMALIGN(4)\
295                 "2:                             \n\t"\
296                 "movq (%%"REG_S", %%"REG_a", 2), %%mm0  \n\t" /* Y1srcData */\
297                 "movq 8(%%"REG_S", %%"REG_a", 2), %%mm2 \n\t" /* Y2srcData */\
298                 "mov 4(%%"REG_d"), %%"REG_S"    \n\t"\
299                 "movq (%%"REG_S", %%"REG_a", 2), %%mm4  \n\t" /* Y1srcData */\
300                 "movq %%mm0, %%mm3              \n\t"\
301                 "punpcklwd %%mm4, %%mm0        \n\t"\
302                 "punpckhwd %%mm4, %%mm3        \n\t"\
303                 "movq 8(%%"REG_d"), %%mm4       \n\t" /* filterCoeff */\
304                 "pmaddwd %%mm4, %%mm0           \n\t"\
305                 "pmaddwd %%mm4, %%mm3           \n\t"\
306                 "paddd %%mm0, %%mm1             \n\t"\
307                 "paddd %%mm3, %%mm5             \n\t"\
308                 "movq 8(%%"REG_S", %%"REG_a", 2), %%mm3 \n\t" /* Y2srcData */\
309                 "mov 16(%%"REG_d"), %%"REG_S"   \n\t"\
310                 "add $16, %%"REG_d"             \n\t"\
311                 "test %%"REG_S", %%"REG_S"      \n\t"\
312                 "movq %%mm2, %%mm0              \n\t"\
313                 "punpcklwd %%mm3, %%mm2        \n\t"\
314                 "punpckhwd %%mm3, %%mm0        \n\t"\
315                 "pmaddwd %%mm4, %%mm2           \n\t"\
316                 "pmaddwd %%mm4, %%mm0           \n\t"\
317                 "paddd %%mm2, %%mm7             \n\t"\
318                 "paddd %%mm0, %%mm6             \n\t"\
319                 " jnz 2b                        \n\t"\
320                 "psrad $16, %%mm1               \n\t"\
321                 "psrad $16, %%mm5               \n\t"\
322                 "psrad $16, %%mm7               \n\t"\
323                 "psrad $16, %%mm6               \n\t"\
324                 "movq "VROUNDER_OFFSET"(%0), %%mm0\n\t"\
325                 "packssdw %%mm5, %%mm1          \n\t"\
326                 "packssdw %%mm6, %%mm7          \n\t"\
327                 "paddw %%mm0, %%mm1             \n\t"\
328                 "paddw %%mm0, %%mm7             \n\t"\
329                 "movq  "U_TEMP"(%0), %%mm3      \n\t"\
330                 "movq  "V_TEMP"(%0), %%mm4      \n\t"\
331
332 #define YSCALEYUV2RGBX \
333                 "psubw "U_OFFSET"(%0), %%mm3    \n\t" /* (U-128)8*/\
334                 "psubw "V_OFFSET"(%0), %%mm4    \n\t" /* (V-128)8*/\
335                 "movq %%mm3, %%mm2              \n\t" /* (U-128)8*/\
336                 "movq %%mm4, %%mm5              \n\t" /* (V-128)8*/\
337                 "pmulhw "UG_COEFF"(%0), %%mm3   \n\t"\
338                 "pmulhw "VG_COEFF"(%0), %%mm4   \n\t"\
339         /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */\
340                 "pmulhw "UB_COEFF"(%0), %%mm2   \n\t"\
341                 "pmulhw "VR_COEFF"(%0), %%mm5   \n\t"\
342                 "psubw "Y_OFFSET"(%0), %%mm1    \n\t" /* 8(Y-16)*/\
343                 "psubw "Y_OFFSET"(%0), %%mm7    \n\t" /* 8(Y-16)*/\
344                 "pmulhw "Y_COEFF"(%0), %%mm1    \n\t"\
345                 "pmulhw "Y_COEFF"(%0), %%mm7    \n\t"\
346         /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */\
347                 "paddw %%mm3, %%mm4             \n\t"\
348                 "movq %%mm2, %%mm0              \n\t"\
349                 "movq %%mm5, %%mm6              \n\t"\
350                 "movq %%mm4, %%mm3              \n\t"\
351                 "punpcklwd %%mm2, %%mm2         \n\t"\
352                 "punpcklwd %%mm5, %%mm5         \n\t"\
353                 "punpcklwd %%mm4, %%mm4         \n\t"\
354                 "paddw %%mm1, %%mm2             \n\t"\
355                 "paddw %%mm1, %%mm5             \n\t"\
356                 "paddw %%mm1, %%mm4             \n\t"\
357                 "punpckhwd %%mm0, %%mm0         \n\t"\
358                 "punpckhwd %%mm6, %%mm6         \n\t"\
359                 "punpckhwd %%mm3, %%mm3         \n\t"\
360                 "paddw %%mm7, %%mm0             \n\t"\
361                 "paddw %%mm7, %%mm6             \n\t"\
362                 "paddw %%mm7, %%mm3             \n\t"\
363                 /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */\
364                 "packuswb %%mm0, %%mm2          \n\t"\
365                 "packuswb %%mm6, %%mm5          \n\t"\
366                 "packuswb %%mm3, %%mm4          \n\t"\
367                 "pxor %%mm7, %%mm7              \n\t"
368 #if 0
369 #define FULL_YSCALEYUV2RGB \
370                 "pxor %%mm7, %%mm7              \n\t"\
371                 "movd %6, %%mm6                 \n\t" /*yalpha1*/\
372                 "punpcklwd %%mm6, %%mm6         \n\t"\
373                 "punpcklwd %%mm6, %%mm6         \n\t"\
374                 "movd %7, %%mm5                 \n\t" /*uvalpha1*/\
375                 "punpcklwd %%mm5, %%mm5         \n\t"\
376                 "punpcklwd %%mm5, %%mm5         \n\t"\
377                 "xor %%"REG_a", %%"REG_a"               \n\t"\
378                 ASMALIGN(4)\
379                 "1:                             \n\t"\
380                 "movq (%0, %%"REG_a", 2), %%mm0 \n\t" /*buf0[eax]*/\
381                 "movq (%1, %%"REG_a", 2), %%mm1 \n\t" /*buf1[eax]*/\
382                 "movq (%2, %%"REG_a",2), %%mm2  \n\t" /* uvbuf0[eax]*/\
383                 "movq (%3, %%"REG_a",2), %%mm3  \n\t" /* uvbuf1[eax]*/\
384                 "psubw %%mm1, %%mm0             \n\t" /* buf0[eax] - buf1[eax]*/\
385                 "psubw %%mm3, %%mm2             \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
386                 "pmulhw %%mm6, %%mm0            \n\t" /* (buf0[eax] - buf1[eax])yalpha1>>16*/\
387                 "pmulhw %%mm5, %%mm2            \n\t" /* (uvbuf0[eax] - uvbuf1[eax])uvalpha1>>16*/\
388                 "psraw $4, %%mm1                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
389                 "movq 4096(%2, %%"REG_a",2), %%mm4      \n\t" /* uvbuf0[eax+2048]*/\
390                 "psraw $4, %%mm3                \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\
391                 "paddw %%mm0, %%mm1             \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
392                 "movq 4096(%3, %%"REG_a",2), %%mm0      \n\t" /* uvbuf1[eax+2048]*/\
393                 "paddw %%mm2, %%mm3             \n\t" /* uvbuf0[eax]uvalpha1 - uvbuf1[eax](1-uvalpha1)*/\
394                 "psubw %%mm0, %%mm4             \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
395                 "psubw "MANGLE(w80)", %%mm1     \n\t" /* 8(Y-16)*/\
396                 "psubw "MANGLE(w400)", %%mm3    \n\t" /* 8(U-128)*/\
397                 "pmulhw "MANGLE(yCoeff)", %%mm1 \n\t"\
398 \
399 \
400                 "pmulhw %%mm5, %%mm4            \n\t" /* (uvbuf0[eax+2048] - uvbuf1[eax+2048])uvalpha1>>16*/\
401                 "movq %%mm3, %%mm2              \n\t" /* (U-128)8*/\
402                 "pmulhw "MANGLE(ubCoeff)", %%mm3\n\t"\
403                 "psraw $4, %%mm0                \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\
404                 "pmulhw "MANGLE(ugCoeff)", %%mm2\n\t"\
405                 "paddw %%mm4, %%mm0             \n\t" /* uvbuf0[eax+2048]uvalpha1 - uvbuf1[eax+2048](1-uvalpha1)*/\
406                 "psubw "MANGLE(w400)", %%mm0    \n\t" /* (V-128)8*/\
407 \
408 \
409                 "movq %%mm0, %%mm4              \n\t" /* (V-128)8*/\
410                 "pmulhw "MANGLE(vrCoeff)", %%mm0\n\t"\
411                 "pmulhw "MANGLE(vgCoeff)", %%mm4\n\t"\
412                 "paddw %%mm1, %%mm3             \n\t" /* B*/\
413                 "paddw %%mm1, %%mm0             \n\t" /* R*/\
414                 "packuswb %%mm3, %%mm3          \n\t"\
415 \
416                 "packuswb %%mm0, %%mm0          \n\t"\
417                 "paddw %%mm4, %%mm2             \n\t"\
418                 "paddw %%mm2, %%mm1             \n\t" /* G*/\
419 \
420                 "packuswb %%mm1, %%mm1          \n\t"
421 #endif
422
423 #define REAL_YSCALEYUV2PACKED(index, c) \
424                 "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0\n\t"\
425                 "movq "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm1\n\t"\
426                 "psraw $3, %%mm0                \n\t"\
427                 "psraw $3, %%mm1                \n\t"\
428                 "movq %%mm0, "CHR_MMX_FILTER_OFFSET"+8("#c")\n\t"\
429                 "movq %%mm1, "LUM_MMX_FILTER_OFFSET"+8("#c")\n\t"\
430                 "xor "#index", "#index"         \n\t"\
431                 ASMALIGN(4)\
432                 "1:                             \n\t"\
433                 "movq (%2, "#index"), %%mm2     \n\t" /* uvbuf0[eax]*/\
434                 "movq (%3, "#index"), %%mm3     \n\t" /* uvbuf1[eax]*/\
435                 "movq 4096(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
436                 "movq 4096(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
437                 "psubw %%mm3, %%mm2             \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
438                 "psubw %%mm4, %%mm5             \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
439                 "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0\n\t"\
440                 "pmulhw %%mm0, %%mm2            \n\t" /* (uvbuf0[eax] - uvbuf1[eax])uvalpha1>>16*/\
441                 "pmulhw %%mm0, %%mm5            \n\t" /* (uvbuf0[eax+2048] - uvbuf1[eax+2048])uvalpha1>>16*/\
442                 "psraw $7, %%mm3                \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\
443                 "psraw $7, %%mm4                \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\
444                 "paddw %%mm2, %%mm3             \n\t" /* uvbuf0[eax]uvalpha1 - uvbuf1[eax](1-uvalpha1)*/\
445                 "paddw %%mm5, %%mm4             \n\t" /* uvbuf0[eax+2048]uvalpha1 - uvbuf1[eax+2048](1-uvalpha1)*/\
446                 "movq (%0, "#index", 2), %%mm0  \n\t" /*buf0[eax]*/\
447                 "movq (%1, "#index", 2), %%mm1  \n\t" /*buf1[eax]*/\
448                 "movq 8(%0, "#index", 2), %%mm6 \n\t" /*buf0[eax]*/\
449                 "movq 8(%1, "#index", 2), %%mm7 \n\t" /*buf1[eax]*/\
450                 "psubw %%mm1, %%mm0             \n\t" /* buf0[eax] - buf1[eax]*/\
451                 "psubw %%mm7, %%mm6             \n\t" /* buf0[eax] - buf1[eax]*/\
452                 "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm0\n\t" /* (buf0[eax] - buf1[eax])yalpha1>>16*/\
453                 "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm6\n\t" /* (buf0[eax] - buf1[eax])yalpha1>>16*/\
454                 "psraw $7, %%mm1                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
455                 "psraw $7, %%mm7                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
456                 "paddw %%mm0, %%mm1             \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
457                 "paddw %%mm6, %%mm7             \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
458                 
459 #define YSCALEYUV2PACKED(index, c)  REAL_YSCALEYUV2PACKED(index, c)
460                 
461 #define REAL_YSCALEYUV2RGB(index, c) \
462                 "xor "#index", "#index" \n\t"\
463                 ASMALIGN(4)\
464                 "1:                             \n\t"\
465                 "movq (%2, "#index"), %%mm2     \n\t" /* uvbuf0[eax]*/\
466                 "movq (%3, "#index"), %%mm3     \n\t" /* uvbuf1[eax]*/\
467                 "movq 4096(%2, "#index"), %%mm5\n\t" /* uvbuf0[eax+2048]*/\
468                 "movq 4096(%3, "#index"), %%mm4\n\t" /* uvbuf1[eax+2048]*/\
469                 "psubw %%mm3, %%mm2             \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\
470                 "psubw %%mm4, %%mm5             \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\
471                 "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0\n\t"\
472                 "pmulhw %%mm0, %%mm2            \n\t" /* (uvbuf0[eax] - uvbuf1[eax])uvalpha1>>16*/\
473                 "pmulhw %%mm0, %%mm5            \n\t" /* (uvbuf0[eax+2048] - uvbuf1[eax+2048])uvalpha1>>16*/\
474                 "psraw $4, %%mm3                \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\
475                 "psraw $4, %%mm4                \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\
476                 "paddw %%mm2, %%mm3             \n\t" /* uvbuf0[eax]uvalpha1 - uvbuf1[eax](1-uvalpha1)*/\
477                 "paddw %%mm5, %%mm4             \n\t" /* uvbuf0[eax+2048]uvalpha1 - uvbuf1[eax+2048](1-uvalpha1)*/\
478                 "psubw "U_OFFSET"("#c"), %%mm3  \n\t" /* (U-128)8*/\
479                 "psubw "V_OFFSET"("#c"), %%mm4  \n\t" /* (V-128)8*/\
480                 "movq %%mm3, %%mm2              \n\t" /* (U-128)8*/\
481                 "movq %%mm4, %%mm5              \n\t" /* (V-128)8*/\
482                 "pmulhw "UG_COEFF"("#c"), %%mm3\n\t"\
483                 "pmulhw "VG_COEFF"("#c"), %%mm4\n\t"\
484         /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */\
485                 "movq (%0, "#index", 2), %%mm0  \n\t" /*buf0[eax]*/\
486                 "movq (%1, "#index", 2), %%mm1  \n\t" /*buf1[eax]*/\
487                 "movq 8(%0, "#index", 2), %%mm6\n\t" /*buf0[eax]*/\
488                 "movq 8(%1, "#index", 2), %%mm7\n\t" /*buf1[eax]*/\
489                 "psubw %%mm1, %%mm0             \n\t" /* buf0[eax] - buf1[eax]*/\
490                 "psubw %%mm7, %%mm6             \n\t" /* buf0[eax] - buf1[eax]*/\
491                 "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm0\n\t" /* (buf0[eax] - buf1[eax])yalpha1>>16*/\
492                 "pmulhw "LUM_MMX_FILTER_OFFSET"+8("#c"), %%mm6\n\t" /* (buf0[eax] - buf1[eax])yalpha1>>16*/\
493                 "psraw $4, %%mm1                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
494                 "psraw $4, %%mm7                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
495                 "paddw %%mm0, %%mm1             \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
496                 "paddw %%mm6, %%mm7             \n\t" /* buf0[eax]yalpha1 + buf1[eax](1-yalpha1) >>16*/\
497                 "pmulhw "UB_COEFF"("#c"), %%mm2\n\t"\
498                 "pmulhw "VR_COEFF"("#c"), %%mm5\n\t"\
499                 "psubw "Y_OFFSET"("#c"), %%mm1  \n\t" /* 8(Y-16)*/\
500                 "psubw "Y_OFFSET"("#c"), %%mm7  \n\t" /* 8(Y-16)*/\
501                 "pmulhw "Y_COEFF"("#c"), %%mm1  \n\t"\
502                 "pmulhw "Y_COEFF"("#c"), %%mm7  \n\t"\
503         /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */\
504                 "paddw %%mm3, %%mm4             \n\t"\
505                 "movq %%mm2, %%mm0              \n\t"\
506                 "movq %%mm5, %%mm6              \n\t"\
507                 "movq %%mm4, %%mm3              \n\t"\
508                 "punpcklwd %%mm2, %%mm2         \n\t"\
509                 "punpcklwd %%mm5, %%mm5         \n\t"\
510                 "punpcklwd %%mm4, %%mm4         \n\t"\
511                 "paddw %%mm1, %%mm2             \n\t"\
512                 "paddw %%mm1, %%mm5             \n\t"\
513                 "paddw %%mm1, %%mm4             \n\t"\
514                 "punpckhwd %%mm0, %%mm0         \n\t"\
515                 "punpckhwd %%mm6, %%mm6         \n\t"\
516                 "punpckhwd %%mm3, %%mm3         \n\t"\
517                 "paddw %%mm7, %%mm0             \n\t"\
518                 "paddw %%mm7, %%mm6             \n\t"\
519                 "paddw %%mm7, %%mm3             \n\t"\
520                 /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */\
521                 "packuswb %%mm0, %%mm2          \n\t"\
522                 "packuswb %%mm6, %%mm5          \n\t"\
523                 "packuswb %%mm3, %%mm4          \n\t"\
524                 "pxor %%mm7, %%mm7              \n\t"
525 #define YSCALEYUV2RGB(index, c)  REAL_YSCALEYUV2RGB(index, c)
526                 
527 #define REAL_YSCALEYUV2PACKED1(index, c) \
528                 "xor "#index", "#index"         \n\t"\
529                 ASMALIGN(4)\
530                 "1:                             \n\t"\
531                 "movq (%2, "#index"), %%mm3     \n\t" /* uvbuf0[eax]*/\
532                 "movq 4096(%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
533                 "psraw $7, %%mm3                \n\t" \
534                 "psraw $7, %%mm4                \n\t" \
535                 "movq (%0, "#index", 2), %%mm1  \n\t" /*buf0[eax]*/\
536                 "movq 8(%0, "#index", 2), %%mm7 \n\t" /*buf0[eax]*/\
537                 "psraw $7, %%mm1                \n\t" \
538                 "psraw $7, %%mm7                \n\t" \
539                 
540 #define YSCALEYUV2PACKED1(index, c)  REAL_YSCALEYUV2PACKED1(index, c)
541                 
542 #define REAL_YSCALEYUV2RGB1(index, c) \
543                 "xor "#index", "#index" \n\t"\
544                 ASMALIGN(4)\
545                 "1:                             \n\t"\
546                 "movq (%2, "#index"), %%mm3     \n\t" /* uvbuf0[eax]*/\
547                 "movq 4096(%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\
548                 "psraw $4, %%mm3                \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\
549                 "psraw $4, %%mm4                \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\
550                 "psubw "U_OFFSET"("#c"), %%mm3  \n\t" /* (U-128)8*/\
551                 "psubw "V_OFFSET"("#c"), %%mm4  \n\t" /* (V-128)8*/\
552                 "movq %%mm3, %%mm2              \n\t" /* (U-128)8*/\
553                 "movq %%mm4, %%mm5              \n\t" /* (V-128)8*/\
554                 "pmulhw "UG_COEFF"("#c"), %%mm3\n\t"\
555                 "pmulhw "VG_COEFF"("#c"), %%mm4\n\t"\
556         /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */\
557                 "movq (%0, "#index", 2), %%mm1  \n\t" /*buf0[eax]*/\
558                 "movq 8(%0, "#index", 2), %%mm7 \n\t" /*buf0[eax]*/\
559                 "psraw $4, %%mm1                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
560                 "psraw $4, %%mm7                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
561                 "pmulhw "UB_COEFF"("#c"), %%mm2\n\t"\
562                 "pmulhw "VR_COEFF"("#c"), %%mm5\n\t"\
563                 "psubw "Y_OFFSET"("#c"), %%mm1  \n\t" /* 8(Y-16)*/\
564                 "psubw "Y_OFFSET"("#c"), %%mm7  \n\t" /* 8(Y-16)*/\
565                 "pmulhw "Y_COEFF"("#c"), %%mm1  \n\t"\
566                 "pmulhw "Y_COEFF"("#c"), %%mm7  \n\t"\
567         /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */\
568                 "paddw %%mm3, %%mm4             \n\t"\
569                 "movq %%mm2, %%mm0              \n\t"\
570                 "movq %%mm5, %%mm6              \n\t"\
571                 "movq %%mm4, %%mm3              \n\t"\
572                 "punpcklwd %%mm2, %%mm2         \n\t"\
573                 "punpcklwd %%mm5, %%mm5         \n\t"\
574                 "punpcklwd %%mm4, %%mm4         \n\t"\
575                 "paddw %%mm1, %%mm2             \n\t"\
576                 "paddw %%mm1, %%mm5             \n\t"\
577                 "paddw %%mm1, %%mm4             \n\t"\
578                 "punpckhwd %%mm0, %%mm0         \n\t"\
579                 "punpckhwd %%mm6, %%mm6         \n\t"\
580                 "punpckhwd %%mm3, %%mm3         \n\t"\
581                 "paddw %%mm7, %%mm0             \n\t"\
582                 "paddw %%mm7, %%mm6             \n\t"\
583                 "paddw %%mm7, %%mm3             \n\t"\
584                 /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */\
585                 "packuswb %%mm0, %%mm2          \n\t"\
586                 "packuswb %%mm6, %%mm5          \n\t"\
587                 "packuswb %%mm3, %%mm4          \n\t"\
588                 "pxor %%mm7, %%mm7              \n\t"
589 #define YSCALEYUV2RGB1(index, c)  REAL_YSCALEYUV2RGB1(index, c)
590
591 #define REAL_YSCALEYUV2PACKED1b(index, c) \
592                 "xor "#index", "#index"         \n\t"\
593                 ASMALIGN(4)\
594                 "1:                             \n\t"\
595                 "movq (%2, "#index"), %%mm2     \n\t" /* uvbuf0[eax]*/\
596                 "movq (%3, "#index"), %%mm3     \n\t" /* uvbuf1[eax]*/\
597                 "movq 4096(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
598                 "movq 4096(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
599                 "paddw %%mm2, %%mm3             \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\
600                 "paddw %%mm5, %%mm4             \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\
601                 "psrlw $8, %%mm3                \n\t" \
602                 "psrlw $8, %%mm4                \n\t" \
603                 "movq (%0, "#index", 2), %%mm1  \n\t" /*buf0[eax]*/\
604                 "movq 8(%0, "#index", 2), %%mm7 \n\t" /*buf0[eax]*/\
605                 "psraw $7, %%mm1                \n\t" \
606                 "psraw $7, %%mm7                \n\t" 
607 #define YSCALEYUV2PACKED1b(index, c)  REAL_YSCALEYUV2PACKED1b(index, c)
608                 
609 // do vertical chrominance interpolation
610 #define REAL_YSCALEYUV2RGB1b(index, c) \
611                 "xor "#index", "#index"         \n\t"\
612                 ASMALIGN(4)\
613                 "1:                             \n\t"\
614                 "movq (%2, "#index"), %%mm2     \n\t" /* uvbuf0[eax]*/\
615                 "movq (%3, "#index"), %%mm3     \n\t" /* uvbuf1[eax]*/\
616                 "movq 4096(%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\
617                 "movq 4096(%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\
618                 "paddw %%mm2, %%mm3             \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\
619                 "paddw %%mm5, %%mm4             \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\
620                 "psrlw $5, %%mm3                \n\t" /*FIXME might overflow*/\
621                 "psrlw $5, %%mm4                \n\t" /*FIXME might overflow*/\
622                 "psubw "U_OFFSET"("#c"), %%mm3  \n\t" /* (U-128)8*/\
623                 "psubw "V_OFFSET"("#c"), %%mm4  \n\t" /* (V-128)8*/\
624                 "movq %%mm3, %%mm2              \n\t" /* (U-128)8*/\
625                 "movq %%mm4, %%mm5              \n\t" /* (V-128)8*/\
626                 "pmulhw "UG_COEFF"("#c"), %%mm3\n\t"\
627                 "pmulhw "VG_COEFF"("#c"), %%mm4\n\t"\
628         /* mm2=(U-128)8, mm3=ug, mm4=vg mm5=(V-128)8 */\
629                 "movq (%0, "#index", 2), %%mm1  \n\t" /*buf0[eax]*/\
630                 "movq 8(%0, "#index", 2), %%mm7 \n\t" /*buf0[eax]*/\
631                 "psraw $4, %%mm1                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
632                 "psraw $4, %%mm7                \n\t" /* buf0[eax] - buf1[eax] >>4*/\
633                 "pmulhw "UB_COEFF"("#c"), %%mm2\n\t"\
634                 "pmulhw "VR_COEFF"("#c"), %%mm5\n\t"\
635                 "psubw "Y_OFFSET"("#c"), %%mm1  \n\t" /* 8(Y-16)*/\
636                 "psubw "Y_OFFSET"("#c"), %%mm7  \n\t" /* 8(Y-16)*/\
637                 "pmulhw "Y_COEFF"("#c"), %%mm1  \n\t"\
638                 "pmulhw "Y_COEFF"("#c"), %%mm7  \n\t"\
639         /* mm1= Y1, mm2=ub, mm3=ug, mm4=vg mm5=vr, mm7=Y2 */\
640                 "paddw %%mm3, %%mm4             \n\t"\
641                 "movq %%mm2, %%mm0              \n\t"\
642                 "movq %%mm5, %%mm6              \n\t"\
643                 "movq %%mm4, %%mm3              \n\t"\
644                 "punpcklwd %%mm2, %%mm2         \n\t"\
645                 "punpcklwd %%mm5, %%mm5         \n\t"\
646                 "punpcklwd %%mm4, %%mm4         \n\t"\
647                 "paddw %%mm1, %%mm2             \n\t"\
648                 "paddw %%mm1, %%mm5             \n\t"\
649                 "paddw %%mm1, %%mm4             \n\t"\
650                 "punpckhwd %%mm0, %%mm0         \n\t"\
651                 "punpckhwd %%mm6, %%mm6         \n\t"\
652                 "punpckhwd %%mm3, %%mm3         \n\t"\
653                 "paddw %%mm7, %%mm0             \n\t"\
654                 "paddw %%mm7, %%mm6             \n\t"\
655                 "paddw %%mm7, %%mm3             \n\t"\
656                 /* mm0=B1, mm2=B2, mm3=G2, mm4=G1, mm5=R1, mm6=R2 */\
657                 "packuswb %%mm0, %%mm2          \n\t"\
658                 "packuswb %%mm6, %%mm5          \n\t"\
659                 "packuswb %%mm3, %%mm4          \n\t"\
660                 "pxor %%mm7, %%mm7              \n\t"
661 #define YSCALEYUV2RGB1b(index, c)  REAL_YSCALEYUV2RGB1b(index, c)
662
663 #define REAL_WRITEBGR32(dst, dstw, index) \
664                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\
665                         "movq %%mm2, %%mm1              \n\t" /* B */\
666                         "movq %%mm5, %%mm6              \n\t" /* R */\
667                         "punpcklbw %%mm4, %%mm2         \n\t" /* GBGBGBGB 0 */\
668                         "punpcklbw %%mm7, %%mm5         \n\t" /* 0R0R0R0R 0 */\
669                         "punpckhbw %%mm4, %%mm1         \n\t" /* GBGBGBGB 2 */\
670                         "punpckhbw %%mm7, %%mm6         \n\t" /* 0R0R0R0R 2 */\
671                         "movq %%mm2, %%mm0              \n\t" /* GBGBGBGB 0 */\
672                         "movq %%mm1, %%mm3              \n\t" /* GBGBGBGB 2 */\
673                         "punpcklwd %%mm5, %%mm0         \n\t" /* 0RGB0RGB 0 */\
674                         "punpckhwd %%mm5, %%mm2         \n\t" /* 0RGB0RGB 1 */\
675                         "punpcklwd %%mm6, %%mm1         \n\t" /* 0RGB0RGB 2 */\
676                         "punpckhwd %%mm6, %%mm3         \n\t" /* 0RGB0RGB 3 */\
677 \
678                         MOVNTQ(%%mm0, (dst, index, 4))\
679                         MOVNTQ(%%mm2, 8(dst, index, 4))\
680                         MOVNTQ(%%mm1, 16(dst, index, 4))\
681                         MOVNTQ(%%mm3, 24(dst, index, 4))\
682 \
683                         "add $8, "#index"               \n\t"\
684                         "cmp "#dstw", "#index"          \n\t"\
685                         " jb 1b                         \n\t"
686 #define WRITEBGR32(dst, dstw, index)  REAL_WRITEBGR32(dst, dstw, index)
687
688 #define REAL_WRITEBGR16(dst, dstw, index) \
689                         "pand "MANGLE(bF8)", %%mm2      \n\t" /* B */\
690                         "pand "MANGLE(bFC)", %%mm4      \n\t" /* G */\
691                         "pand "MANGLE(bF8)", %%mm5      \n\t" /* R */\
692                         "psrlq $3, %%mm2                \n\t"\
693 \
694                         "movq %%mm2, %%mm1              \n\t"\
695                         "movq %%mm4, %%mm3              \n\t"\
696 \
697                         "punpcklbw %%mm7, %%mm3         \n\t"\
698                         "punpcklbw %%mm5, %%mm2         \n\t"\
699                         "punpckhbw %%mm7, %%mm4         \n\t"\
700                         "punpckhbw %%mm5, %%mm1         \n\t"\
701 \
702                         "psllq $3, %%mm3                \n\t"\
703                         "psllq $3, %%mm4                \n\t"\
704 \
705                         "por %%mm3, %%mm2               \n\t"\
706                         "por %%mm4, %%mm1               \n\t"\
707 \
708                         MOVNTQ(%%mm2, (dst, index, 2))\
709                         MOVNTQ(%%mm1, 8(dst, index, 2))\
710 \
711                         "add $8, "#index"               \n\t"\
712                         "cmp "#dstw", "#index"          \n\t"\
713                         " jb 1b                         \n\t"
714 #define WRITEBGR16(dst, dstw, index)  REAL_WRITEBGR16(dst, dstw, index)
715
716 #define REAL_WRITEBGR15(dst, dstw, index) \
717                         "pand "MANGLE(bF8)", %%mm2      \n\t" /* B */\
718                         "pand "MANGLE(bF8)", %%mm4      \n\t" /* G */\
719                         "pand "MANGLE(bF8)", %%mm5      \n\t" /* R */\
720                         "psrlq $3, %%mm2                \n\t"\
721                         "psrlq $1, %%mm5                \n\t"\
722 \
723                         "movq %%mm2, %%mm1              \n\t"\
724                         "movq %%mm4, %%mm3              \n\t"\
725 \
726                         "punpcklbw %%mm7, %%mm3         \n\t"\
727                         "punpcklbw %%mm5, %%mm2         \n\t"\
728                         "punpckhbw %%mm7, %%mm4         \n\t"\
729                         "punpckhbw %%mm5, %%mm1         \n\t"\
730 \
731                         "psllq $2, %%mm3                \n\t"\
732                         "psllq $2, %%mm4                \n\t"\
733 \
734                         "por %%mm3, %%mm2               \n\t"\
735                         "por %%mm4, %%mm1               \n\t"\
736 \
737                         MOVNTQ(%%mm2, (dst, index, 2))\
738                         MOVNTQ(%%mm1, 8(dst, index, 2))\
739 \
740                         "add $8, "#index"               \n\t"\
741                         "cmp "#dstw", "#index"          \n\t"\
742                         " jb 1b                         \n\t"
743 #define WRITEBGR15(dst, dstw, index)  REAL_WRITEBGR15(dst, dstw, index)
744
745 #define WRITEBGR24OLD(dst, dstw, index) \
746                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\
747                         "movq %%mm2, %%mm1              \n\t" /* B */\
748                         "movq %%mm5, %%mm6              \n\t" /* R */\
749                         "punpcklbw %%mm4, %%mm2         \n\t" /* GBGBGBGB 0 */\
750                         "punpcklbw %%mm7, %%mm5         \n\t" /* 0R0R0R0R 0 */\
751                         "punpckhbw %%mm4, %%mm1         \n\t" /* GBGBGBGB 2 */\
752                         "punpckhbw %%mm7, %%mm6         \n\t" /* 0R0R0R0R 2 */\
753                         "movq %%mm2, %%mm0              \n\t" /* GBGBGBGB 0 */\
754                         "movq %%mm1, %%mm3              \n\t" /* GBGBGBGB 2 */\
755                         "punpcklwd %%mm5, %%mm0         \n\t" /* 0RGB0RGB 0 */\
756                         "punpckhwd %%mm5, %%mm2         \n\t" /* 0RGB0RGB 1 */\
757                         "punpcklwd %%mm6, %%mm1         \n\t" /* 0RGB0RGB 2 */\
758                         "punpckhwd %%mm6, %%mm3         \n\t" /* 0RGB0RGB 3 */\
759 \
760                         "movq %%mm0, %%mm4              \n\t" /* 0RGB0RGB 0 */\
761                         "psrlq $8, %%mm0                \n\t" /* 00RGB0RG 0 */\
762                         "pand "MANGLE(bm00000111)", %%mm4\n\t" /* 00000RGB 0 */\
763                         "pand "MANGLE(bm11111000)", %%mm0\n\t" /* 00RGB000 0.5 */\
764                         "por %%mm4, %%mm0               \n\t" /* 00RGBRGB 0 */\
765                         "movq %%mm2, %%mm4              \n\t" /* 0RGB0RGB 1 */\
766                         "psllq $48, %%mm2               \n\t" /* GB000000 1 */\
767                         "por %%mm2, %%mm0               \n\t" /* GBRGBRGB 0 */\
768 \
769                         "movq %%mm4, %%mm2              \n\t" /* 0RGB0RGB 1 */\
770                         "psrld $16, %%mm4               \n\t" /* 000R000R 1 */\
771                         "psrlq $24, %%mm2               \n\t" /* 0000RGB0 1.5 */\
772                         "por %%mm4, %%mm2               \n\t" /* 000RRGBR 1 */\
773                         "pand "MANGLE(bm00001111)", %%mm2\n\t" /* 0000RGBR 1 */\
774                         "movq %%mm1, %%mm4              \n\t" /* 0RGB0RGB 2 */\
775                         "psrlq $8, %%mm1                \n\t" /* 00RGB0RG 2 */\
776                         "pand "MANGLE(bm00000111)", %%mm4\n\t" /* 00000RGB 2 */\
777                         "pand "MANGLE(bm11111000)", %%mm1\n\t" /* 00RGB000 2.5 */\
778                         "por %%mm4, %%mm1               \n\t" /* 00RGBRGB 2 */\
779                         "movq %%mm1, %%mm4              \n\t" /* 00RGBRGB 2 */\
780                         "psllq $32, %%mm1               \n\t" /* BRGB0000 2 */\
781                         "por %%mm1, %%mm2               \n\t" /* BRGBRGBR 1 */\
782 \
783                         "psrlq $32, %%mm4               \n\t" /* 000000RG 2.5 */\
784                         "movq %%mm3, %%mm5              \n\t" /* 0RGB0RGB 3 */\
785                         "psrlq $8, %%mm3                \n\t" /* 00RGB0RG 3 */\
786                         "pand "MANGLE(bm00000111)", %%mm5\n\t" /* 00000RGB 3 */\
787                         "pand "MANGLE(bm11111000)", %%mm3\n\t" /* 00RGB000 3.5 */\
788                         "por %%mm5, %%mm3               \n\t" /* 00RGBRGB 3 */\
789                         "psllq $16, %%mm3               \n\t" /* RGBRGB00 3 */\
790                         "por %%mm4, %%mm3               \n\t" /* RGBRGBRG 2.5 */\
791 \
792                         MOVNTQ(%%mm0, (dst))\
793                         MOVNTQ(%%mm2, 8(dst))\
794                         MOVNTQ(%%mm3, 16(dst))\
795                         "add $24, "#dst"                \n\t"\
796 \
797                         "add $8, "#index"               \n\t"\
798                         "cmp "#dstw", "#index"          \n\t"\
799                         " jb 1b                         \n\t"
800
801 #define WRITEBGR24MMX(dst, dstw, index) \
802                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\
803                         "movq %%mm2, %%mm1              \n\t" /* B */\
804                         "movq %%mm5, %%mm6              \n\t" /* R */\
805                         "punpcklbw %%mm4, %%mm2         \n\t" /* GBGBGBGB 0 */\
806                         "punpcklbw %%mm7, %%mm5         \n\t" /* 0R0R0R0R 0 */\
807                         "punpckhbw %%mm4, %%mm1         \n\t" /* GBGBGBGB 2 */\
808                         "punpckhbw %%mm7, %%mm6         \n\t" /* 0R0R0R0R 2 */\
809                         "movq %%mm2, %%mm0              \n\t" /* GBGBGBGB 0 */\
810                         "movq %%mm1, %%mm3              \n\t" /* GBGBGBGB 2 */\
811                         "punpcklwd %%mm5, %%mm0         \n\t" /* 0RGB0RGB 0 */\
812                         "punpckhwd %%mm5, %%mm2         \n\t" /* 0RGB0RGB 1 */\
813                         "punpcklwd %%mm6, %%mm1         \n\t" /* 0RGB0RGB 2 */\
814                         "punpckhwd %%mm6, %%mm3         \n\t" /* 0RGB0RGB 3 */\
815 \
816                         "movq %%mm0, %%mm4              \n\t" /* 0RGB0RGB 0 */\
817                         "movq %%mm2, %%mm6              \n\t" /* 0RGB0RGB 1 */\
818                         "movq %%mm1, %%mm5              \n\t" /* 0RGB0RGB 2 */\
819                         "movq %%mm3, %%mm7              \n\t" /* 0RGB0RGB 3 */\
820 \
821                         "psllq $40, %%mm0               \n\t" /* RGB00000 0 */\
822                         "psllq $40, %%mm2               \n\t" /* RGB00000 1 */\
823                         "psllq $40, %%mm1               \n\t" /* RGB00000 2 */\
824                         "psllq $40, %%mm3               \n\t" /* RGB00000 3 */\
825 \
826                         "punpckhdq %%mm4, %%mm0         \n\t" /* 0RGBRGB0 0 */\
827                         "punpckhdq %%mm6, %%mm2         \n\t" /* 0RGBRGB0 1 */\
828                         "punpckhdq %%mm5, %%mm1         \n\t" /* 0RGBRGB0 2 */\
829                         "punpckhdq %%mm7, %%mm3         \n\t" /* 0RGBRGB0 3 */\
830 \
831                         "psrlq $8, %%mm0                \n\t" /* 00RGBRGB 0 */\
832                         "movq %%mm2, %%mm6              \n\t" /* 0RGBRGB0 1 */\
833                         "psllq $40, %%mm2               \n\t" /* GB000000 1 */\
834                         "por %%mm2, %%mm0               \n\t" /* GBRGBRGB 0 */\
835                         MOVNTQ(%%mm0, (dst))\
836 \
837                         "psrlq $24, %%mm6               \n\t" /* 0000RGBR 1 */\
838                         "movq %%mm1, %%mm5              \n\t" /* 0RGBRGB0 2 */\
839                         "psllq $24, %%mm1               \n\t" /* BRGB0000 2 */\
840                         "por %%mm1, %%mm6               \n\t" /* BRGBRGBR 1 */\
841                         MOVNTQ(%%mm6, 8(dst))\
842 \
843                         "psrlq $40, %%mm5               \n\t" /* 000000RG 2 */\
844                         "psllq $8, %%mm3                \n\t" /* RGBRGB00 3 */\
845                         "por %%mm3, %%mm5               \n\t" /* RGBRGBRG 2 */\
846                         MOVNTQ(%%mm5, 16(dst))\
847 \
848                         "add $24, "#dst"                \n\t"\
849 \
850                         "add $8, "#index"                       \n\t"\
851                         "cmp "#dstw", "#index"                  \n\t"\
852                         " jb 1b                         \n\t"
853
854 #define WRITEBGR24MMX2(dst, dstw, index) \
855                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\
856                         "movq "MANGLE(M24A)", %%mm0     \n\t"\
857                         "movq "MANGLE(M24C)", %%mm7     \n\t"\
858                         "pshufw $0x50, %%mm2, %%mm1     \n\t" /* B3 B2 B3 B2  B1 B0 B1 B0 */\
859                         "pshufw $0x50, %%mm4, %%mm3     \n\t" /* G3 G2 G3 G2  G1 G0 G1 G0 */\
860                         "pshufw $0x00, %%mm5, %%mm6     \n\t" /* R1 R0 R1 R0  R1 R0 R1 R0 */\
861 \
862                         "pand %%mm0, %%mm1              \n\t" /*    B2        B1       B0 */\
863                         "pand %%mm0, %%mm3              \n\t" /*    G2        G1       G0 */\
864                         "pand %%mm7, %%mm6              \n\t" /*       R1        R0       */\
865 \
866                         "psllq $8, %%mm3                \n\t" /* G2        G1       G0    */\
867                         "por %%mm1, %%mm6               \n\t"\
868                         "por %%mm3, %%mm6               \n\t"\
869                         MOVNTQ(%%mm6, (dst))\
870 \
871                         "psrlq $8, %%mm4                \n\t" /* 00 G7 G6 G5  G4 G3 G2 G1 */\
872                         "pshufw $0xA5, %%mm2, %%mm1     \n\t" /* B5 B4 B5 B4  B3 B2 B3 B2 */\
873                         "pshufw $0x55, %%mm4, %%mm3     \n\t" /* G4 G3 G4 G3  G4 G3 G4 G3 */\
874                         "pshufw $0xA5, %%mm5, %%mm6     \n\t" /* R5 R4 R5 R4  R3 R2 R3 R2 */\
875 \
876                         "pand "MANGLE(M24B)", %%mm1     \n\t" /* B5       B4        B3    */\
877                         "pand %%mm7, %%mm3              \n\t" /*       G4        G3       */\
878                         "pand %%mm0, %%mm6              \n\t" /*    R4        R3       R2 */\
879 \
880                         "por %%mm1, %%mm3               \n\t" /* B5    G4 B4     G3 B3    */\
881                         "por %%mm3, %%mm6               \n\t"\
882                         MOVNTQ(%%mm6, 8(dst))\
883 \
884                         "pshufw $0xFF, %%mm2, %%mm1     \n\t" /* B7 B6 B7 B6  B7 B6 B6 B7 */\
885                         "pshufw $0xFA, %%mm4, %%mm3     \n\t" /* 00 G7 00 G7  G6 G5 G6 G5 */\
886                         "pshufw $0xFA, %%mm5, %%mm6     \n\t" /* R7 R6 R7 R6  R5 R4 R5 R4 */\
887 \
888                         "pand %%mm7, %%mm1              \n\t" /*       B7        B6       */\
889                         "pand %%mm0, %%mm3              \n\t" /*    G7        G6       G5 */\
890                         "pand "MANGLE(M24B)", %%mm6     \n\t" /* R7       R6        R5    */\
891 \
892                         "por %%mm1, %%mm3               \n\t"\
893                         "por %%mm3, %%mm6               \n\t"\
894                         MOVNTQ(%%mm6, 16(dst))\
895 \
896                         "add $24, "#dst"                \n\t"\
897 \
898                         "add $8, "#index"               \n\t"\
899                         "cmp "#dstw", "#index"          \n\t"\
900                         " jb 1b                         \n\t"
901
902 #ifdef HAVE_MMX2
903 #undef WRITEBGR24
904 #define WRITEBGR24(dst, dstw, index)  WRITEBGR24MMX2(dst, dstw, index)
905 #else
906 #undef WRITEBGR24
907 #define WRITEBGR24(dst, dstw, index)  WRITEBGR24MMX(dst, dstw, index)
908 #endif
909
910 #define REAL_WRITEYUY2(dst, dstw, index) \
911                         "packuswb %%mm3, %%mm3          \n\t"\
912                         "packuswb %%mm4, %%mm4          \n\t"\
913                         "packuswb %%mm7, %%mm1          \n\t"\
914                         "punpcklbw %%mm4, %%mm3         \n\t"\
915                         "movq %%mm1, %%mm7              \n\t"\
916                         "punpcklbw %%mm3, %%mm1         \n\t"\
917                         "punpckhbw %%mm3, %%mm7         \n\t"\
918 \
919                         MOVNTQ(%%mm1, (dst, index, 2))\
920                         MOVNTQ(%%mm7, 8(dst, index, 2))\
921 \
922                         "add $8, "#index"               \n\t"\
923                         "cmp "#dstw", "#index"          \n\t"\
924                         " jb 1b                         \n\t"
925 #define WRITEYUY2(dst, dstw, index)  REAL_WRITEYUY2(dst, dstw, index)
926
927
928 static inline void RENAME(yuv2yuvX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
929                                     int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
930                                     uint8_t *dest, uint8_t *uDest, uint8_t *vDest, long dstW, long chrDstW)
931 {
932 #ifdef HAVE_MMX
933         if(c->flags & SWS_ACCURATE_RND){
934                 if(uDest){
935                         YSCALEYUV2YV12X_ACCURATE(   0, CHR_MMX_FILTER_OFFSET, uDest, chrDstW)
936                         YSCALEYUV2YV12X_ACCURATE(4096, CHR_MMX_FILTER_OFFSET, vDest, chrDstW)
937                 }
938
939                 YSCALEYUV2YV12X_ACCURATE(0, LUM_MMX_FILTER_OFFSET, dest, dstW)
940         }else{
941                 if(uDest){
942                         YSCALEYUV2YV12X(   0, CHR_MMX_FILTER_OFFSET, uDest, chrDstW)
943                         YSCALEYUV2YV12X(4096, CHR_MMX_FILTER_OFFSET, vDest, chrDstW)
944                 }
945
946                 YSCALEYUV2YV12X(0, LUM_MMX_FILTER_OFFSET, dest, dstW)
947         }
948 #else
949 #ifdef HAVE_ALTIVEC
950 yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize,
951                       chrFilter, chrSrc, chrFilterSize,
952                       dest, uDest, vDest, dstW, chrDstW);
953 #else //HAVE_ALTIVEC
954 yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,
955             chrFilter, chrSrc, chrFilterSize,
956             dest, uDest, vDest, dstW, chrDstW);
957 #endif //!HAVE_ALTIVEC
958 #endif
959 }
960
961 static inline void RENAME(yuv2nv12X)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
962                                      int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
963                                      uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
964 {
965 yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize,
966              chrFilter, chrSrc, chrFilterSize,
967              dest, uDest, dstW, chrDstW, dstFormat);
968 }
969
970 static inline void RENAME(yuv2yuv1)(int16_t *lumSrc, int16_t *chrSrc,
971                                     uint8_t *dest, uint8_t *uDest, uint8_t *vDest, long dstW, long chrDstW)
972 {
973 #ifdef HAVE_MMX
974         if(uDest != NULL)
975         {
976                 asm volatile(
977                                 YSCALEYUV2YV121
978                                 :: "r" (chrSrc + chrDstW), "r" (uDest + chrDstW),
979                                 "g" (-chrDstW)
980                                 : "%"REG_a
981                         );
982
983                 asm volatile(
984                                 YSCALEYUV2YV121
985                                 :: "r" (chrSrc + 2048 + chrDstW), "r" (vDest + chrDstW),
986                                 "g" (-chrDstW)
987                                 : "%"REG_a
988                         );
989         }
990
991         asm volatile(
992                 YSCALEYUV2YV121
993                 :: "r" (lumSrc + dstW), "r" (dest + dstW),
994                 "g" (-dstW)
995                 : "%"REG_a
996         );
997 #else
998         int i;
999         for(i=0; i<dstW; i++)
1000         {
1001                 int val= lumSrc[i]>>7;
1002                 
1003                 if(val&256){
1004                         if(val<0) val=0;
1005                         else      val=255;
1006                 }
1007
1008                 dest[i]= val;
1009         }
1010
1011         if(uDest != NULL)
1012                 for(i=0; i<chrDstW; i++)
1013                 {
1014                         int u=chrSrc[i]>>7;
1015                         int v=chrSrc[i + 2048]>>7;
1016
1017                         if((u|v)&256){
1018                                 if(u<0)         u=0;
1019                                 else if (u>255) u=255;
1020                                 if(v<0)         v=0;
1021                                 else if (v>255) v=255;
1022                         }
1023
1024                         uDest[i]= u;
1025                         vDest[i]= v;
1026                 }
1027 #endif
1028 }
1029
1030
1031 /**
1032  * vertical scale YV12 to RGB
1033  */
1034 static inline void RENAME(yuv2packedX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
1035                                     int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
1036                             uint8_t *dest, long dstW, long dstY)
1037 {
1038 #ifdef HAVE_MMX
1039     long dummy=0;
1040     if(c->flags & SWS_ACCURATE_RND){
1041                 switch(c->dstFormat){
1042                 case PIX_FMT_RGB32:
1043                                 YSCALEYUV2PACKEDX_ACCURATE
1044                                 YSCALEYUV2RGBX
1045                                 WRITEBGR32(%4, %5, %%REGa)
1046
1047                                 YSCALEYUV2PACKEDX_END
1048                         return;
1049                 case PIX_FMT_BGR24:
1050                                 YSCALEYUV2PACKEDX_ACCURATE
1051                                 YSCALEYUV2RGBX
1052                                 "lea (%%"REG_a", %%"REG_a", 2), %%"REG_c"\n\t" //FIXME optimize
1053                                 "add %4, %%"REG_c"                      \n\t"
1054                                 WRITEBGR24(%%REGc, %5, %%REGa)
1055
1056
1057                         :: "r" (&c->redDither), 
1058                            "m" (dummy), "m" (dummy), "m" (dummy),
1059                            "r" (dest), "m" (dstW)
1060                         : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S
1061                         );
1062                         return;
1063                 case PIX_FMT_BGR555:
1064                                 YSCALEYUV2PACKEDX_ACCURATE
1065                                 YSCALEYUV2RGBX
1066                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1067 #ifdef DITHER1XBPP
1068                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1069                                 "paddusb "MANGLE(g5Dither)", %%mm4\n\t"
1070                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1071 #endif
1072
1073                                 WRITEBGR15(%4, %5, %%REGa)
1074                                 YSCALEYUV2PACKEDX_END
1075                         return;
1076                 case PIX_FMT_BGR565:
1077                                 YSCALEYUV2PACKEDX_ACCURATE
1078                                 YSCALEYUV2RGBX
1079                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1080 #ifdef DITHER1XBPP
1081                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1082                                 "paddusb "MANGLE(g6Dither)", %%mm4\n\t"
1083                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1084 #endif
1085
1086                                 WRITEBGR16(%4, %5, %%REGa)
1087                                 YSCALEYUV2PACKEDX_END
1088                         return;
1089                 case PIX_FMT_YUYV422:
1090                                 YSCALEYUV2PACKEDX_ACCURATE
1091                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1092
1093                                 "psraw $3, %%mm3                \n\t"
1094                                 "psraw $3, %%mm4                \n\t"
1095                                 "psraw $3, %%mm1                \n\t"
1096                                 "psraw $3, %%mm7                \n\t"
1097                                 WRITEYUY2(%4, %5, %%REGa)
1098                                 YSCALEYUV2PACKEDX_END
1099                         return;
1100                 }
1101     }else{
1102         switch(c->dstFormat)
1103         {
1104         case PIX_FMT_RGB32:
1105                                 YSCALEYUV2PACKEDX
1106                                 YSCALEYUV2RGBX
1107                                 WRITEBGR32(%4, %5, %%REGa)
1108                                 YSCALEYUV2PACKEDX_END
1109                 return;
1110         case PIX_FMT_BGR24:
1111                                 YSCALEYUV2PACKEDX
1112                                 YSCALEYUV2RGBX
1113                                 "lea (%%"REG_a", %%"REG_a", 2), %%"REG_c"\n\t" //FIXME optimize
1114                                 "add %4, %%"REG_c"                      \n\t"
1115                                 WRITEBGR24(%%REGc, %5, %%REGa)
1116
1117                         :: "r" (&c->redDither), 
1118                            "m" (dummy), "m" (dummy), "m" (dummy),
1119                            "r" (dest), "m" (dstW)
1120                         : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S
1121                         );
1122                 return;
1123         case PIX_FMT_BGR555:
1124                                 YSCALEYUV2PACKEDX
1125                                 YSCALEYUV2RGBX
1126                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1127 #ifdef DITHER1XBPP
1128                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1129                                 "paddusb "MANGLE(g5Dither)", %%mm4\n\t"
1130                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1131 #endif
1132
1133                                 WRITEBGR15(%4, %5, %%REGa)
1134                                 YSCALEYUV2PACKEDX_END
1135                 return;
1136         case PIX_FMT_BGR565:
1137                                 YSCALEYUV2PACKEDX
1138                                 YSCALEYUV2RGBX
1139                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1140 #ifdef DITHER1XBPP
1141                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1142                                 "paddusb "MANGLE(g6Dither)", %%mm4\n\t"
1143                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1144 #endif
1145
1146                                 WRITEBGR16(%4, %5, %%REGa)
1147                                 YSCALEYUV2PACKEDX_END
1148                 return;
1149         case PIX_FMT_YUYV422:
1150                                 YSCALEYUV2PACKEDX
1151                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1152
1153                                 "psraw $3, %%mm3                \n\t"
1154                                 "psraw $3, %%mm4                \n\t"
1155                                 "psraw $3, %%mm1                \n\t"
1156                                 "psraw $3, %%mm7                \n\t"
1157                                 WRITEYUY2(%4, %5, %%REGa)
1158                                 YSCALEYUV2PACKEDX_END
1159                 return;
1160         }
1161     }
1162 #endif
1163 #ifdef HAVE_ALTIVEC
1164                 /* The following list of supported dstFormat values should
1165                    match what's found in the body of altivec_yuv2packedX() */
1166                 if(c->dstFormat==PIX_FMT_ABGR  || c->dstFormat==PIX_FMT_BGRA  ||
1167                    c->dstFormat==PIX_FMT_BGR24 || c->dstFormat==PIX_FMT_RGB24 ||
1168                    c->dstFormat==PIX_FMT_RGBA  || c->dstFormat==PIX_FMT_ARGB)
1169                         altivec_yuv2packedX (c, lumFilter, lumSrc, lumFilterSize,
1170                                     chrFilter, chrSrc, chrFilterSize,
1171                                     dest, dstW, dstY);
1172                 else
1173 #endif
1174                         yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,
1175                                     chrFilter, chrSrc, chrFilterSize,
1176                                     dest, dstW, dstY);
1177 }
1178
1179 /**
1180  * vertical bilinear scale YV12 to RGB
1181  */
1182 static inline void RENAME(yuv2packed2)(SwsContext *c, uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1,
1183                             uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
1184 {
1185         int yalpha1=yalpha^4095;
1186         int uvalpha1=uvalpha^4095;
1187         int i;
1188
1189 #if 0 //isn't used
1190         if(flags&SWS_FULL_CHR_H_INT)
1191         {
1192                 switch(dstFormat)
1193                 {
1194 #ifdef HAVE_MMX
1195                 case PIX_FMT_RGB32:
1196                         asm volatile(
1197
1198
1199 FULL_YSCALEYUV2RGB
1200                         "punpcklbw %%mm1, %%mm3         \n\t" // BGBGBGBG
1201                         "punpcklbw %%mm7, %%mm0         \n\t" // R0R0R0R0
1202
1203                         "movq %%mm3, %%mm1              \n\t"
1204                         "punpcklwd %%mm0, %%mm3         \n\t" // BGR0BGR0
1205                         "punpckhwd %%mm0, %%mm1         \n\t" // BGR0BGR0
1206
1207                         MOVNTQ(%%mm3, (%4, %%REGa, 4))
1208                         MOVNTQ(%%mm1, 8(%4, %%REGa, 4))
1209
1210                         "add $4, %%"REG_a"              \n\t"
1211                         "cmp %5, %%"REG_a"              \n\t"
1212                         " jb 1b                         \n\t"
1213
1214
1215                         :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" ((long)dstW),
1216                         "m" (yalpha1), "m" (uvalpha1)
1217                         : "%"REG_a
1218                         );
1219                         break;
1220                 case PIX_FMT_BGR24:
1221                         asm volatile(
1222
1223 FULL_YSCALEYUV2RGB
1224
1225                                                                 // lsb ... msb
1226                         "punpcklbw %%mm1, %%mm3         \n\t" // BGBGBGBG
1227                         "punpcklbw %%mm7, %%mm0         \n\t" // R0R0R0R0
1228
1229                         "movq %%mm3, %%mm1              \n\t"
1230                         "punpcklwd %%mm0, %%mm3         \n\t" // BGR0BGR0
1231                         "punpckhwd %%mm0, %%mm1         \n\t" // BGR0BGR0
1232
1233                         "movq %%mm3, %%mm2              \n\t" // BGR0BGR0
1234                         "psrlq $8, %%mm3                \n\t" // GR0BGR00
1235                         "pand "MANGLE(bm00000111)", %%mm2\n\t" // BGR00000
1236                         "pand "MANGLE(bm11111000)", %%mm3\n\t" // 000BGR00
1237                         "por %%mm2, %%mm3               \n\t" // BGRBGR00
1238                         "movq %%mm1, %%mm2              \n\t"
1239                         "psllq $48, %%mm1               \n\t" // 000000BG
1240                         "por %%mm1, %%mm3               \n\t" // BGRBGRBG
1241
1242                         "movq %%mm2, %%mm1              \n\t" // BGR0BGR0
1243                         "psrld $16, %%mm2               \n\t" // R000R000
1244                         "psrlq $24, %%mm1               \n\t" // 0BGR0000
1245                         "por %%mm2, %%mm1               \n\t" // RBGRR000
1246
1247                         "mov %4, %%"REG_b"              \n\t"
1248                         "add %%"REG_a", %%"REG_b"       \n\t"
1249
1250 #ifdef HAVE_MMX2
1251                         //FIXME Alignment
1252                         "movntq %%mm3, (%%"REG_b", %%"REG_a", 2)\n\t"
1253                         "movntq %%mm1, 8(%%"REG_b", %%"REG_a", 2)\n\t"
1254 #else
1255                         "movd %%mm3, (%%"REG_b", %%"REG_a", 2)  \n\t"
1256                         "psrlq $32, %%mm3               \n\t"
1257                         "movd %%mm3, 4(%%"REG_b", %%"REG_a", 2) \n\t"
1258                         "movd %%mm1, 8(%%"REG_b", %%"REG_a", 2) \n\t"
1259 #endif
1260                         "add $4, %%"REG_a"              \n\t"
1261                         "cmp %5, %%"REG_a"              \n\t"
1262                         " jb 1b                         \n\t"
1263
1264                         :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest), "m" (dstW),
1265                         "m" (yalpha1), "m" (uvalpha1)
1266                         : "%"REG_a, "%"REG_b
1267                         );
1268                         break;
1269                 case PIX_FMT_BGR555:
1270                         asm volatile(
1271
1272 FULL_YSCALEYUV2RGB
1273 #ifdef DITHER1XBPP
1274                         "paddusb "MANGLE(g5Dither)", %%mm1\n\t"
1275                         "paddusb "MANGLE(r5Dither)", %%mm0\n\t"
1276                         "paddusb "MANGLE(b5Dither)", %%mm3\n\t"
1277 #endif
1278                         "punpcklbw %%mm7, %%mm1         \n\t" // 0G0G0G0G
1279                         "punpcklbw %%mm7, %%mm3         \n\t" // 0B0B0B0B
1280                         "punpcklbw %%mm7, %%mm0         \n\t" // 0R0R0R0R
1281
1282                         "psrlw $3, %%mm3                \n\t"
1283                         "psllw $2, %%mm1                \n\t"
1284                         "psllw $7, %%mm0                \n\t"
1285                         "pand "MANGLE(g15Mask)", %%mm1  \n\t"
1286                         "pand "MANGLE(r15Mask)", %%mm0  \n\t"
1287
1288                         "por %%mm3, %%mm1               \n\t"
1289                         "por %%mm1, %%mm0               \n\t"
1290
1291                         MOVNTQ(%%mm0, (%4, %%REGa, 2))
1292
1293                         "add $4, %%"REG_a"              \n\t"
1294                         "cmp %5, %%"REG_a"              \n\t"
1295                         " jb 1b                         \n\t"
1296
1297                         :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),
1298                         "m" (yalpha1), "m" (uvalpha1)
1299                         : "%"REG_a
1300                         );
1301                         break;
1302                 case PIX_FMT_BGR565:
1303                         asm volatile(
1304
1305 FULL_YSCALEYUV2RGB
1306 #ifdef DITHER1XBPP
1307                         "paddusb "MANGLE(g6Dither)", %%mm1\n\t"
1308                         "paddusb "MANGLE(r5Dither)", %%mm0\n\t"
1309                         "paddusb "MANGLE(b5Dither)", %%mm3\n\t"
1310 #endif
1311                         "punpcklbw %%mm7, %%mm1         \n\t" // 0G0G0G0G
1312                         "punpcklbw %%mm7, %%mm3         \n\t" // 0B0B0B0B
1313                         "punpcklbw %%mm7, %%mm0         \n\t" // 0R0R0R0R
1314
1315                         "psrlw $3, %%mm3                \n\t"
1316                         "psllw $3, %%mm1                \n\t"
1317                         "psllw $8, %%mm0                \n\t"
1318                         "pand "MANGLE(g16Mask)", %%mm1  \n\t"
1319                         "pand "MANGLE(r16Mask)", %%mm0  \n\t"
1320
1321                         "por %%mm3, %%mm1               \n\t"
1322                         "por %%mm1, %%mm0               \n\t"
1323
1324                         MOVNTQ(%%mm0, (%4, %%REGa, 2))
1325
1326                         "add $4, %%"REG_a"              \n\t"
1327                         "cmp %5, %%"REG_a"              \n\t"
1328                         " jb 1b                         \n\t"
1329
1330                         :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),
1331                         "m" (yalpha1), "m" (uvalpha1)
1332                         : "%"REG_a
1333                         );
1334                 break;
1335 #endif
1336                 case PIX_FMT_BGR32:
1337 #ifndef HAVE_MMX
1338                 case PIX_FMT_RGB32:
1339 #endif
1340                 if(dstFormat==PIX_FMT_RGB32)
1341                 {
1342                         int i;
1343 #ifdef WORDS_BIGENDIAN
1344                         dest++;
1345 #endif
1346                         for(i=0;i<dstW;i++){
1347                                 // vertical linear interpolation && yuv2rgb in a single step:
1348                                 int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
1349                                 int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
1350                                 int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
1351                                 dest[0]=clip_table[((Y + yuvtab_40cf[U]) >>13)];
1352                                 dest[1]=clip_table[((Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13)];
1353                                 dest[2]=clip_table[((Y + yuvtab_3343[V]) >>13)];
1354                                 dest+= 4;
1355                         }
1356                 }
1357                 else if(dstFormat==PIX_FMT_BGR24)
1358                 {
1359                         int i;
1360                         for(i=0;i<dstW;i++){
1361                                 // vertical linear interpolation && yuv2rgb in a single step:
1362                                 int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
1363                                 int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
1364                                 int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
1365                                 dest[0]=clip_table[((Y + yuvtab_40cf[U]) >>13)];
1366                                 dest[1]=clip_table[((Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13)];
1367                                 dest[2]=clip_table[((Y + yuvtab_3343[V]) >>13)];
1368                                 dest+= 3;
1369                         }
1370                 }
1371                 else if(dstFormat==PIX_FMT_BGR565)
1372                 {
1373                         int i;
1374                         for(i=0;i<dstW;i++){
1375                                 // vertical linear interpolation && yuv2rgb in a single step:
1376                                 int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
1377                                 int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
1378                                 int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
1379
1380                                 ((uint16_t*)dest)[i] =
1381                                         clip_table16b[(Y + yuvtab_40cf[U]) >>13] |
1382                                         clip_table16g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |
1383                                         clip_table16r[(Y + yuvtab_3343[V]) >>13];
1384                         }
1385                 }
1386                 else if(dstFormat==PIX_FMT_BGR555)
1387                 {
1388                         int i;
1389                         for(i=0;i<dstW;i++){
1390                                 // vertical linear interpolation && yuv2rgb in a single step:
1391                                 int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
1392                                 int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
1393                                 int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
1394
1395                                 ((uint16_t*)dest)[i] =
1396                                         clip_table15b[(Y + yuvtab_40cf[U]) >>13] |
1397                                         clip_table15g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |
1398                                         clip_table15r[(Y + yuvtab_3343[V]) >>13];
1399                         }
1400                 }
1401         }//FULL_UV_IPOL
1402         else
1403         {
1404 #endif // if 0
1405 #ifdef HAVE_MMX
1406         switch(c->dstFormat)
1407         {
1408 //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
1409         case PIX_FMT_RGB32:
1410                         asm volatile(
1411                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1412                                 "mov %4, %%"REG_b"                      \n\t"
1413                                 "push %%"REG_BP"                        \n\t"
1414                                 YSCALEYUV2RGB(%%REGBP, %5)
1415                                 WRITEBGR32(%%REGb, 8280(%5), %%REGBP)
1416                                 "pop %%"REG_BP"                         \n\t"
1417                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1418
1419                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1420                         "a" (&c->redDither)
1421                         );
1422                         return;
1423         case PIX_FMT_BGR24:
1424                         asm volatile(
1425                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1426                                 "mov %4, %%"REG_b"                      \n\t"
1427                                 "push %%"REG_BP"                        \n\t"
1428                                 YSCALEYUV2RGB(%%REGBP, %5)
1429                                 WRITEBGR24(%%REGb, 8280(%5), %%REGBP)
1430                                 "pop %%"REG_BP"                         \n\t"
1431                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1432                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1433                         "a" (&c->redDither)
1434                         );
1435                         return;
1436         case PIX_FMT_BGR555:
1437                         asm volatile(
1438                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1439                                 "mov %4, %%"REG_b"                      \n\t"
1440                                 "push %%"REG_BP"                        \n\t"
1441                                 YSCALEYUV2RGB(%%REGBP, %5)
1442                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1443 #ifdef DITHER1XBPP
1444                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1445                                 "paddusb "MANGLE(g5Dither)", %%mm4\n\t"
1446                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1447 #endif
1448
1449                                 WRITEBGR15(%%REGb, 8280(%5), %%REGBP)
1450                                 "pop %%"REG_BP"                         \n\t"
1451                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1452
1453                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1454                         "a" (&c->redDither)
1455                         );
1456                         return;
1457         case PIX_FMT_BGR565:
1458                         asm volatile(
1459                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1460                                 "mov %4, %%"REG_b"                      \n\t"
1461                                 "push %%"REG_BP"                        \n\t"
1462                                 YSCALEYUV2RGB(%%REGBP, %5)
1463                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1464 #ifdef DITHER1XBPP
1465                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1466                                 "paddusb "MANGLE(g6Dither)", %%mm4\n\t"
1467                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1468 #endif
1469
1470                                 WRITEBGR16(%%REGb, 8280(%5), %%REGBP)
1471                                 "pop %%"REG_BP"                         \n\t"
1472                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1473                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1474                         "a" (&c->redDither)
1475                         );
1476                         return;
1477         case PIX_FMT_YUYV422:
1478                         asm volatile(
1479                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1480                                 "mov %4, %%"REG_b"                      \n\t"
1481                                 "push %%"REG_BP"                        \n\t"
1482                                 YSCALEYUV2PACKED(%%REGBP, %5)
1483                                 WRITEYUY2(%%REGb, 8280(%5), %%REGBP)
1484                                 "pop %%"REG_BP"                         \n\t"
1485                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1486                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1487                         "a" (&c->redDither)
1488                         );
1489                         return;
1490         default: break;
1491         }
1492 #endif //HAVE_MMX
1493 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C)
1494 }
1495
1496 /**
1497  * YV12 to RGB without scaling or interpolating
1498  */
1499 static inline void RENAME(yuv2packed1)(SwsContext *c, uint16_t *buf0, uint16_t *uvbuf0, uint16_t *uvbuf1,
1500                             uint8_t *dest, int dstW, int uvalpha, int dstFormat, int flags, int y)
1501 {
1502         const int yalpha1=0;
1503         int i;
1504         
1505         uint16_t *buf1= buf0; //FIXME needed for the rgb1/bgr1
1506         const int yalpha= 4096; //FIXME ...
1507
1508         if(flags&SWS_FULL_CHR_H_INT)
1509         {
1510                 RENAME(yuv2packed2)(c, buf0, buf0, uvbuf0, uvbuf1, dest, dstW, 0, uvalpha, y);
1511                 return;
1512         }
1513
1514 #ifdef HAVE_MMX
1515         if( uvalpha < 2048 ) // note this is not correct (shifts chrominance by 0.5 pixels) but its a bit faster
1516         {
1517                 switch(dstFormat)
1518                 {
1519                 case PIX_FMT_RGB32:
1520                         asm volatile(
1521                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1522                                 "mov %4, %%"REG_b"                      \n\t"
1523                                 "push %%"REG_BP"                        \n\t"
1524                                 YSCALEYUV2RGB1(%%REGBP, %5)
1525                                 WRITEBGR32(%%REGb, 8280(%5), %%REGBP)
1526                                 "pop %%"REG_BP"                         \n\t"
1527                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1528
1529                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1530                         "a" (&c->redDither)
1531                         );
1532                         return;
1533                 case PIX_FMT_BGR24:
1534                         asm volatile(
1535                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1536                                 "mov %4, %%"REG_b"                      \n\t"
1537                                 "push %%"REG_BP"                        \n\t"
1538                                 YSCALEYUV2RGB1(%%REGBP, %5)
1539                                 WRITEBGR24(%%REGb, 8280(%5), %%REGBP)
1540                                 "pop %%"REG_BP"                         \n\t"
1541                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1542
1543                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1544                         "a" (&c->redDither)
1545                         );
1546                         return;
1547                 case PIX_FMT_BGR555:
1548                         asm volatile(
1549                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1550                                 "mov %4, %%"REG_b"                      \n\t"
1551                                 "push %%"REG_BP"                        \n\t"
1552                                 YSCALEYUV2RGB1(%%REGBP, %5)
1553                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1554 #ifdef DITHER1XBPP
1555                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1556                                 "paddusb "MANGLE(g5Dither)", %%mm4\n\t"
1557                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1558 #endif
1559                                 WRITEBGR15(%%REGb, 8280(%5), %%REGBP)
1560                                 "pop %%"REG_BP"                         \n\t"
1561                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1562
1563                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1564                         "a" (&c->redDither)
1565                         );
1566                         return;
1567                 case PIX_FMT_BGR565:
1568                         asm volatile(
1569                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1570                                 "mov %4, %%"REG_b"                      \n\t"
1571                                 "push %%"REG_BP"                        \n\t"
1572                                 YSCALEYUV2RGB1(%%REGBP, %5)
1573                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1574 #ifdef DITHER1XBPP
1575                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1576                                 "paddusb "MANGLE(g6Dither)", %%mm4\n\t"
1577                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1578 #endif
1579
1580                                 WRITEBGR16(%%REGb, 8280(%5), %%REGBP)
1581                                 "pop %%"REG_BP"                         \n\t"
1582                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1583
1584                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1585                         "a" (&c->redDither)
1586                         );
1587                         return;
1588                 case PIX_FMT_YUYV422:
1589                         asm volatile(
1590                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1591                                 "mov %4, %%"REG_b"                      \n\t"
1592                                 "push %%"REG_BP"                        \n\t"
1593                                 YSCALEYUV2PACKED1(%%REGBP, %5)
1594                                 WRITEYUY2(%%REGb, 8280(%5), %%REGBP)
1595                                 "pop %%"REG_BP"                         \n\t"
1596                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1597
1598                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1599                         "a" (&c->redDither)
1600                         );
1601                         return;
1602                 }
1603         }
1604         else
1605         {
1606                 switch(dstFormat)
1607                 {
1608                 case PIX_FMT_RGB32:
1609                         asm volatile(
1610                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1611                                 "mov %4, %%"REG_b"                      \n\t"
1612                                 "push %%"REG_BP"                        \n\t"
1613                                 YSCALEYUV2RGB1b(%%REGBP, %5)
1614                                 WRITEBGR32(%%REGb, 8280(%5), %%REGBP)
1615                                 "pop %%"REG_BP"                         \n\t"
1616                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1617
1618                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1619                         "a" (&c->redDither)
1620                         );
1621                         return;
1622                 case PIX_FMT_BGR24:
1623                         asm volatile(
1624                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1625                                 "mov %4, %%"REG_b"                      \n\t"
1626                                 "push %%"REG_BP"                        \n\t"
1627                                 YSCALEYUV2RGB1b(%%REGBP, %5)
1628                                 WRITEBGR24(%%REGb, 8280(%5), %%REGBP)
1629                                 "pop %%"REG_BP"                         \n\t"
1630                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1631
1632                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1633                         "a" (&c->redDither)
1634                         );
1635                         return;
1636                 case PIX_FMT_BGR555:
1637                         asm volatile(
1638                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1639                                 "mov %4, %%"REG_b"                      \n\t"
1640                                 "push %%"REG_BP"                        \n\t"
1641                                 YSCALEYUV2RGB1b(%%REGBP, %5)
1642                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1643 #ifdef DITHER1XBPP
1644                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1645                                 "paddusb "MANGLE(g5Dither)", %%mm4\n\t"
1646                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1647 #endif
1648                                 WRITEBGR15(%%REGb, 8280(%5), %%REGBP)
1649                                 "pop %%"REG_BP"                         \n\t"
1650                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1651
1652                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1653                         "a" (&c->redDither)
1654                         );
1655                         return;
1656                 case PIX_FMT_BGR565:
1657                         asm volatile(
1658                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1659                                 "mov %4, %%"REG_b"                      \n\t"
1660                                 "push %%"REG_BP"                        \n\t"
1661                                 YSCALEYUV2RGB1b(%%REGBP, %5)
1662                 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
1663 #ifdef DITHER1XBPP
1664                                 "paddusb "MANGLE(b5Dither)", %%mm2\n\t"
1665                                 "paddusb "MANGLE(g6Dither)", %%mm4\n\t"
1666                                 "paddusb "MANGLE(r5Dither)", %%mm5\n\t"
1667 #endif
1668
1669                                 WRITEBGR16(%%REGb, 8280(%5), %%REGBP)
1670                                 "pop %%"REG_BP"                         \n\t"
1671                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1672
1673                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1674                         "a" (&c->redDither)
1675                         );
1676                         return;
1677                 case PIX_FMT_YUYV422:
1678                         asm volatile(
1679                                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
1680                                 "mov %4, %%"REG_b"                      \n\t"
1681                                 "push %%"REG_BP"                        \n\t"
1682                                 YSCALEYUV2PACKED1b(%%REGBP, %5)
1683                                 WRITEYUY2(%%REGb, 8280(%5), %%REGBP)
1684                                 "pop %%"REG_BP"                         \n\t"
1685                                 "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
1686
1687                         :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
1688                         "a" (&c->redDither)
1689                         );
1690                         return;
1691                 }
1692         }
1693 #endif
1694         if( uvalpha < 2048 )
1695         {
1696                 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C)
1697         }else{
1698                 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C)
1699         }
1700 }
1701
1702 //FIXME yuy2* can read upto 7 samples to much
1703
1704 static inline void RENAME(yuy2ToY)(uint8_t *dst, uint8_t *src, long width)
1705 {
1706 #ifdef HAVE_MMX
1707         asm volatile(
1708                 "movq "MANGLE(bm01010101)", %%mm2\n\t"
1709                 "mov %0, %%"REG_a"              \n\t"
1710                 "1:                             \n\t"
1711                 "movq (%1, %%"REG_a",2), %%mm0  \n\t"
1712                 "movq 8(%1, %%"REG_a",2), %%mm1 \n\t"
1713                 "pand %%mm2, %%mm0              \n\t"
1714                 "pand %%mm2, %%mm1              \n\t"
1715                 "packuswb %%mm1, %%mm0          \n\t"
1716                 "movq %%mm0, (%2, %%"REG_a")    \n\t"
1717                 "add $8, %%"REG_a"              \n\t"
1718                 " js 1b                         \n\t"
1719                 : : "g" (-width), "r" (src+width*2), "r" (dst+width)
1720                 : "%"REG_a
1721         );
1722 #else
1723         int i;
1724         for(i=0; i<width; i++)
1725                 dst[i]= src[2*i];
1726 #endif
1727 }
1728
1729 static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, long width)
1730 {
1731 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
1732         asm volatile(
1733                 "movq "MANGLE(bm01010101)", %%mm4\n\t"
1734                 "mov %0, %%"REG_a"              \n\t"
1735                 "1:                             \n\t"
1736                 "movq (%1, %%"REG_a",4), %%mm0  \n\t"
1737                 "movq 8(%1, %%"REG_a",4), %%mm1 \n\t"
1738                 "movq (%2, %%"REG_a",4), %%mm2  \n\t"
1739                 "movq 8(%2, %%"REG_a",4), %%mm3 \n\t"
1740                 PAVGB(%%mm2, %%mm0)
1741                 PAVGB(%%mm3, %%mm1)
1742                 "psrlw $8, %%mm0                \n\t"
1743                 "psrlw $8, %%mm1                \n\t"
1744                 "packuswb %%mm1, %%mm0          \n\t"
1745                 "movq %%mm0, %%mm1              \n\t"
1746                 "psrlw $8, %%mm0                \n\t"
1747                 "pand %%mm4, %%mm1              \n\t"
1748                 "packuswb %%mm0, %%mm0          \n\t"
1749                 "packuswb %%mm1, %%mm1          \n\t"
1750                 "movd %%mm0, (%4, %%"REG_a")    \n\t"
1751                 "movd %%mm1, (%3, %%"REG_a")    \n\t"
1752                 "add $4, %%"REG_a"              \n\t"
1753                 " js 1b                         \n\t"
1754                 : : "g" (-width), "r" (src1+width*4), "r" (src2+width*4), "r" (dstU+width), "r" (dstV+width)
1755                 : "%"REG_a
1756         );
1757 #else
1758         int i;
1759         for(i=0; i<width; i++)
1760         {
1761                 dstU[i]= (src1[4*i + 1] + src2[4*i + 1])>>1;
1762                 dstV[i]= (src1[4*i + 3] + src2[4*i + 3])>>1;
1763         }
1764 #endif
1765 }
1766
1767 //this is allmost identical to the previous, end exists only cuz yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses
1768 static inline void RENAME(uyvyToY)(uint8_t *dst, uint8_t *src, long width)
1769 {
1770 #ifdef HAVE_MMX
1771         asm volatile(
1772                 "mov %0, %%"REG_a"              \n\t"
1773                 "1:                             \n\t"
1774                 "movq (%1, %%"REG_a",2), %%mm0  \n\t"
1775                 "movq 8(%1, %%"REG_a",2), %%mm1 \n\t"
1776                 "psrlw $8, %%mm0                \n\t"
1777                 "psrlw $8, %%mm1                \n\t"
1778                 "packuswb %%mm1, %%mm0          \n\t"
1779                 "movq %%mm0, (%2, %%"REG_a")    \n\t"
1780                 "add $8, %%"REG_a"              \n\t"
1781                 " js 1b                         \n\t"
1782                 : : "g" (-width), "r" (src+width*2), "r" (dst+width)
1783                 : "%"REG_a
1784         );
1785 #else
1786         int i;
1787         for(i=0; i<width; i++)
1788                 dst[i]= src[2*i+1];
1789 #endif
1790 }
1791
1792 static inline void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, long width)
1793 {
1794 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
1795         asm volatile(
1796                 "movq "MANGLE(bm01010101)", %%mm4\n\t"
1797                 "mov %0, %%"REG_a"              \n\t"
1798                 "1:                             \n\t"
1799                 "movq (%1, %%"REG_a",4), %%mm0  \n\t"
1800                 "movq 8(%1, %%"REG_a",4), %%mm1 \n\t"
1801                 "movq (%2, %%"REG_a",4), %%mm2  \n\t"
1802                 "movq 8(%2, %%"REG_a",4), %%mm3 \n\t"
1803                 PAVGB(%%mm2, %%mm0)
1804                 PAVGB(%%mm3, %%mm1)
1805                 "pand %%mm4, %%mm0              \n\t"
1806                 "pand %%mm4, %%mm1              \n\t"
1807                 "packuswb %%mm1, %%mm0          \n\t"
1808                 "movq %%mm0, %%mm1              \n\t"
1809                 "psrlw $8, %%mm0                \n\t"
1810                 "pand %%mm4, %%mm1              \n\t"
1811                 "packuswb %%mm0, %%mm0          \n\t"
1812                 "packuswb %%mm1, %%mm1          \n\t"
1813                 "movd %%mm0, (%4, %%"REG_a")    \n\t"
1814                 "movd %%mm1, (%3, %%"REG_a")    \n\t"
1815                 "add $4, %%"REG_a"              \n\t"
1816                 " js 1b                         \n\t"
1817                 : : "g" (-width), "r" (src1+width*4), "r" (src2+width*4), "r" (dstU+width), "r" (dstV+width)
1818                 : "%"REG_a
1819         );
1820 #else
1821         int i;
1822         for(i=0; i<width; i++)
1823         {
1824                 dstU[i]= (src1[4*i + 0] + src2[4*i + 0])>>1;
1825                 dstV[i]= (src1[4*i + 2] + src2[4*i + 2])>>1;
1826         }
1827 #endif
1828 }
1829
1830 static inline void RENAME(bgr32ToY)(uint8_t *dst, uint8_t *src, int width)
1831 {
1832         int i;
1833         for(i=0; i<width; i++)
1834         {
1835                 int b=  ((uint32_t*)src)[i]&0xFF;
1836                 int g= (((uint32_t*)src)[i]>>8)&0xFF;
1837                 int r= (((uint32_t*)src)[i]>>16)&0xFF;
1838
1839                 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
1840         }
1841 }
1842
1843 static inline void RENAME(bgr32ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
1844 {
1845         int i;
1846         for(i=0; i<width; i++)
1847         {
1848                 const int a= ((uint32_t*)src1)[2*i+0];
1849                 const int e= ((uint32_t*)src1)[2*i+1];
1850                 const int c= ((uint32_t*)src2)[2*i+0];
1851                 const int d= ((uint32_t*)src2)[2*i+1];
1852                 const int l= (a&0xFF00FF) + (e&0xFF00FF) + (c&0xFF00FF) + (d&0xFF00FF);
1853                 const int h= (a&0x00FF00) + (e&0x00FF00) + (c&0x00FF00) + (d&0x00FF00);
1854                 const int b=  l&0x3FF;
1855                 const int g=  h>>8;
1856                 const int r=  l>>16;
1857
1858                 dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
1859                 dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
1860         }
1861 }
1862
1863 static inline void RENAME(bgr24ToY)(uint8_t *dst, uint8_t *src, long width)
1864 {
1865 #ifdef HAVE_MMX
1866         asm volatile(
1867                 "mov %2, %%"REG_a"              \n\t"
1868                 "movq "MANGLE(bgr2YCoeff)", %%mm6               \n\t"
1869                 "movq "MANGLE(w1111)", %%mm5            \n\t"
1870                 "pxor %%mm7, %%mm7              \n\t"
1871                 "lea (%%"REG_a", %%"REG_a", 2), %%"REG_d"\n\t"
1872                 ASMALIGN(4)
1873                 "1:                             \n\t"
1874                 PREFETCH" 64(%0, %%"REG_d")     \n\t"
1875                 "movd (%0, %%"REG_d"), %%mm0    \n\t"
1876                 "movd 3(%0, %%"REG_d"), %%mm1   \n\t"
1877                 "punpcklbw %%mm7, %%mm0         \n\t"
1878                 "punpcklbw %%mm7, %%mm1         \n\t"
1879                 "movd 6(%0, %%"REG_d"), %%mm2   \n\t"
1880                 "movd 9(%0, %%"REG_d"), %%mm3   \n\t"
1881                 "punpcklbw %%mm7, %%mm2         \n\t"
1882                 "punpcklbw %%mm7, %%mm3         \n\t"
1883                 "pmaddwd %%mm6, %%mm0           \n\t"
1884                 "pmaddwd %%mm6, %%mm1           \n\t"
1885                 "pmaddwd %%mm6, %%mm2           \n\t"
1886                 "pmaddwd %%mm6, %%mm3           \n\t"
1887 #ifndef FAST_BGR2YV12
1888                 "psrad $8, %%mm0                \n\t"
1889                 "psrad $8, %%mm1                \n\t"
1890                 "psrad $8, %%mm2                \n\t"
1891                 "psrad $8, %%mm3                \n\t"
1892 #endif
1893                 "packssdw %%mm1, %%mm0          \n\t"
1894                 "packssdw %%mm3, %%mm2          \n\t"
1895                 "pmaddwd %%mm5, %%mm0           \n\t"
1896                 "pmaddwd %%mm5, %%mm2           \n\t"
1897                 "packssdw %%mm2, %%mm0          \n\t"
1898                 "psraw $7, %%mm0                \n\t"
1899
1900                 "movd 12(%0, %%"REG_d"), %%mm4  \n\t"
1901                 "movd 15(%0, %%"REG_d"), %%mm1  \n\t"
1902                 "punpcklbw %%mm7, %%mm4         \n\t"
1903                 "punpcklbw %%mm7, %%mm1         \n\t"
1904                 "movd 18(%0, %%"REG_d"), %%mm2  \n\t"
1905                 "movd 21(%0, %%"REG_d"), %%mm3  \n\t"
1906                 "punpcklbw %%mm7, %%mm2         \n\t"
1907                 "punpcklbw %%mm7, %%mm3         \n\t"
1908                 "pmaddwd %%mm6, %%mm4           \n\t"
1909                 "pmaddwd %%mm6, %%mm1           \n\t"
1910                 "pmaddwd %%mm6, %%mm2           \n\t"
1911                 "pmaddwd %%mm6, %%mm3           \n\t"
1912 #ifndef FAST_BGR2YV12
1913                 "psrad $8, %%mm4                \n\t"
1914                 "psrad $8, %%mm1                \n\t"
1915                 "psrad $8, %%mm2                \n\t"
1916                 "psrad $8, %%mm3                \n\t"
1917 #endif
1918                 "packssdw %%mm1, %%mm4          \n\t"
1919                 "packssdw %%mm3, %%mm2          \n\t"
1920                 "pmaddwd %%mm5, %%mm4           \n\t"
1921                 "pmaddwd %%mm5, %%mm2           \n\t"
1922                 "add $24, %%"REG_d"             \n\t"
1923                 "packssdw %%mm2, %%mm4          \n\t"
1924                 "psraw $7, %%mm4                \n\t"
1925
1926                 "packuswb %%mm4, %%mm0          \n\t"
1927                 "paddusb "MANGLE(bgr2YOffset)", %%mm0   \n\t"
1928
1929                 "movq %%mm0, (%1, %%"REG_a")    \n\t"
1930                 "add $8, %%"REG_a"              \n\t"
1931                 " js 1b                         \n\t"
1932                 : : "r" (src+width*3), "r" (dst+width), "g" (-width)
1933                 : "%"REG_a, "%"REG_d
1934         );
1935 #else
1936         int i;
1937         for(i=0; i<width; i++)
1938         {
1939                 int b= src[i*3+0];
1940                 int g= src[i*3+1];
1941                 int r= src[i*3+2];
1942
1943                 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
1944         }
1945 #endif
1946 }
1947
1948 static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, long width)
1949 {
1950 #ifdef HAVE_MMX
1951         asm volatile(
1952                 "mov %4, %%"REG_a"              \n\t"
1953                 "movq "MANGLE(w1111)", %%mm5            \n\t"
1954                 "movq "MANGLE(bgr2UCoeff)", %%mm6               \n\t"
1955                 "pxor %%mm7, %%mm7              \n\t"
1956                 "lea (%%"REG_a", %%"REG_a", 2), %%"REG_d"       \n\t"
1957                 "add %%"REG_d", %%"REG_d"       \n\t"
1958                 ASMALIGN(4)
1959                 "1:                             \n\t"
1960                 PREFETCH" 64(%0, %%"REG_d")     \n\t"
1961                 PREFETCH" 64(%1, %%"REG_d")     \n\t"
1962 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
1963                 "movq (%0, %%"REG_d"), %%mm0    \n\t"
1964                 "movq (%1, %%"REG_d"), %%mm1    \n\t"
1965                 "movq 6(%0, %%"REG_d"), %%mm2   \n\t"
1966                 "movq 6(%1, %%"REG_d"), %%mm3   \n\t"
1967                 PAVGB(%%mm1, %%mm0)
1968                 PAVGB(%%mm3, %%mm2)
1969                 "movq %%mm0, %%mm1              \n\t"
1970                 "movq %%mm2, %%mm3              \n\t"
1971                 "psrlq $24, %%mm0               \n\t"
1972                 "psrlq $24, %%mm2               \n\t"
1973                 PAVGB(%%mm1, %%mm0)
1974                 PAVGB(%%mm3, %%mm2)
1975                 "punpcklbw %%mm7, %%mm0         \n\t"
1976                 "punpcklbw %%mm7, %%mm2         \n\t"
1977 #else
1978                 "movd (%0, %%"REG_d"), %%mm0    \n\t"
1979                 "movd (%1, %%"REG_d"), %%mm1    \n\t"
1980                 "movd 3(%0, %%"REG_d"), %%mm2   \n\t"
1981                 "movd 3(%1, %%"REG_d"), %%mm3   \n\t"
1982                 "punpcklbw %%mm7, %%mm0         \n\t"
1983                 "punpcklbw %%mm7, %%mm1         \n\t"
1984                 "punpcklbw %%mm7, %%mm2         \n\t"
1985                 "punpcklbw %%mm7, %%mm3         \n\t"
1986                 "paddw %%mm1, %%mm0             \n\t"
1987                 "paddw %%mm3, %%mm2             \n\t"
1988                 "paddw %%mm2, %%mm0             \n\t"
1989                 "movd 6(%0, %%"REG_d"), %%mm4   \n\t"
1990                 "movd 6(%1, %%"REG_d"), %%mm1   \n\t"
1991                 "movd 9(%0, %%"REG_d"), %%mm2   \n\t"
1992                 "movd 9(%1, %%"REG_d"), %%mm3   \n\t"
1993                 "punpcklbw %%mm7, %%mm4         \n\t"
1994                 "punpcklbw %%mm7, %%mm1         \n\t"
1995                 "punpcklbw %%mm7, %%mm2         \n\t"
1996                 "punpcklbw %%mm7, %%mm3         \n\t"
1997                 "paddw %%mm1, %%mm4             \n\t"
1998                 "paddw %%mm3, %%mm2             \n\t"
1999                 "paddw %%mm4, %%mm2             \n\t"
2000                 "psrlw $2, %%mm0                \n\t"
2001                 "psrlw $2, %%mm2                \n\t"
2002 #endif
2003                 "movq "MANGLE(bgr2VCoeff)", %%mm1               \n\t"
2004                 "movq "MANGLE(bgr2VCoeff)", %%mm3               \n\t"
2005                 
2006                 "pmaddwd %%mm0, %%mm1           \n\t"
2007                 "pmaddwd %%mm2, %%mm3           \n\t"
2008                 "pmaddwd %%mm6, %%mm0           \n\t"
2009                 "pmaddwd %%mm6, %%mm2           \n\t"
2010 #ifndef FAST_BGR2YV12
2011                 "psrad $8, %%mm0                \n\t"
2012                 "psrad $8, %%mm1                \n\t"
2013                 "psrad $8, %%mm2                \n\t"
2014                 "psrad $8, %%mm3                \n\t"
2015 #endif
2016                 "packssdw %%mm2, %%mm0          \n\t"
2017                 "packssdw %%mm3, %%mm1          \n\t"
2018                 "pmaddwd %%mm5, %%mm0           \n\t"
2019                 "pmaddwd %%mm5, %%mm1           \n\t"
2020                 "packssdw %%mm1, %%mm0          \n\t" // V1 V0 U1 U0
2021                 "psraw $7, %%mm0                \n\t"
2022
2023 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
2024                 "movq 12(%0, %%"REG_d"), %%mm4  \n\t"
2025                 "movq 12(%1, %%"REG_d"), %%mm1  \n\t"
2026                 "movq 18(%0, %%"REG_d"), %%mm2  \n\t"
2027                 "movq 18(%1, %%"REG_d"), %%mm3  \n\t"
2028                 PAVGB(%%mm1, %%mm4)
2029                 PAVGB(%%mm3, %%mm2)
2030                 "movq %%mm4, %%mm1              \n\t"
2031                 "movq %%mm2, %%mm3              \n\t"
2032                 "psrlq $24, %%mm4               \n\t"
2033                 "psrlq $24, %%mm2               \n\t"
2034                 PAVGB(%%mm1, %%mm4)
2035                 PAVGB(%%mm3, %%mm2)
2036                 "punpcklbw %%mm7, %%mm4         \n\t"
2037                 "punpcklbw %%mm7, %%mm2         \n\t"
2038 #else
2039                 "movd 12(%0, %%"REG_d"), %%mm4  \n\t"
2040                 "movd 12(%1, %%"REG_d"), %%mm1  \n\t"
2041                 "movd 15(%0, %%"REG_d"), %%mm2  \n\t"
2042                 "movd 15(%1, %%"REG_d"), %%mm3  \n\t"
2043                 "punpcklbw %%mm7, %%mm4         \n\t"
2044                 "punpcklbw %%mm7, %%mm1         \n\t"
2045                 "punpcklbw %%mm7, %%mm2         \n\t"
2046                 "punpcklbw %%mm7, %%mm3         \n\t"
2047                 "paddw %%mm1, %%mm4             \n\t"
2048                 "paddw %%mm3, %%mm2             \n\t"
2049                 "paddw %%mm2, %%mm4             \n\t"
2050                 "movd 18(%0, %%"REG_d"), %%mm5  \n\t"
2051                 "movd 18(%1, %%"REG_d"), %%mm1  \n\t"
2052                 "movd 21(%0, %%"REG_d"), %%mm2  \n\t"
2053                 "movd 21(%1, %%"REG_d"), %%mm3  \n\t"
2054                 "punpcklbw %%mm7, %%mm5         \n\t"
2055                 "punpcklbw %%mm7, %%mm1         \n\t"
2056                 "punpcklbw %%mm7, %%mm2         \n\t"
2057                 "punpcklbw %%mm7, %%mm3         \n\t"
2058                 "paddw %%mm1, %%mm5             \n\t"
2059                 "paddw %%mm3, %%mm2             \n\t"
2060                 "paddw %%mm5, %%mm2             \n\t"
2061                 "movq "MANGLE(w1111)", %%mm5            \n\t"
2062                 "psrlw $2, %%mm4                \n\t"
2063                 "psrlw $2, %%mm2                \n\t"
2064 #endif
2065                 "movq "MANGLE(bgr2VCoeff)", %%mm1               \n\t"
2066                 "movq "MANGLE(bgr2VCoeff)", %%mm3               \n\t"
2067                 
2068                 "pmaddwd %%mm4, %%mm1           \n\t"
2069                 "pmaddwd %%mm2, %%mm3           \n\t"
2070                 "pmaddwd %%mm6, %%mm4           \n\t"
2071                 "pmaddwd %%mm6, %%mm2           \n\t"
2072 #ifndef FAST_BGR2YV12
2073                 "psrad $8, %%mm4                \n\t"
2074                 "psrad $8, %%mm1                \n\t"
2075                 "psrad $8, %%mm2                \n\t"
2076                 "psrad $8, %%mm3                \n\t"
2077 #endif
2078                 "packssdw %%mm2, %%mm4          \n\t"
2079                 "packssdw %%mm3, %%mm1          \n\t"
2080                 "pmaddwd %%mm5, %%mm4           \n\t"
2081                 "pmaddwd %%mm5, %%mm1           \n\t"
2082                 "add $24, %%"REG_d"             \n\t"
2083                 "packssdw %%mm1, %%mm4          \n\t" // V3 V2 U3 U2
2084                 "psraw $7, %%mm4                \n\t"
2085                 
2086                 "movq %%mm0, %%mm1              \n\t"
2087                 "punpckldq %%mm4, %%mm0         \n\t"
2088                 "punpckhdq %%mm4, %%mm1         \n\t"
2089                 "packsswb %%mm1, %%mm0          \n\t"
2090                 "paddb "MANGLE(bgr2UVOffset)", %%mm0    \n\t"
2091
2092                 "movd %%mm0, (%2, %%"REG_a")    \n\t"
2093                 "punpckhdq %%mm0, %%mm0         \n\t"
2094                 "movd %%mm0, (%3, %%"REG_a")    \n\t"
2095                 "add $4, %%"REG_a"              \n\t"
2096                 " js 1b                         \n\t"
2097                 : : "r" (src1+width*6), "r" (src2+width*6), "r" (dstU+width), "r" (dstV+width), "g" (-width)
2098                 : "%"REG_a, "%"REG_d
2099         );
2100 #else
2101         int i;
2102         for(i=0; i<width; i++)
2103         {
2104                 int b= src1[6*i + 0] + src1[6*i + 3] + src2[6*i + 0] + src2[6*i + 3];
2105                 int g= src1[6*i + 1] + src1[6*i + 4] + src2[6*i + 1] + src2[6*i + 4];
2106                 int r= src1[6*i + 2] + src1[6*i + 5] + src2[6*i + 2] + src2[6*i + 5];
2107
2108                 dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
2109                 dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
2110         }
2111 #endif
2112 }
2113
2114 static inline void RENAME(bgr16ToY)(uint8_t *dst, uint8_t *src, int width)
2115 {
2116         int i;
2117         for(i=0; i<width; i++)
2118         {
2119                 int d= ((uint16_t*)src)[i];
2120                 int b= d&0x1F;
2121                 int g= (d>>5)&0x3F;
2122                 int r= (d>>11)&0x1F;
2123
2124                 dst[i]= ((2*RY*r + GY*g + 2*BY*b)>>(RGB2YUV_SHIFT-2)) + 16;
2125         }
2126 }
2127
2128 static inline void RENAME(bgr16ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
2129 {
2130         int i;
2131         for(i=0; i<width; i++)
2132         {
2133                 int d0= ((uint32_t*)src1)[i];
2134                 int d1= ((uint32_t*)src2)[i];
2135                 
2136                 int dl= (d0&0x07E0F81F) + (d1&0x07E0F81F);
2137                 int dh= ((d0>>5)&0x07C0F83F) + ((d1>>5)&0x07C0F83F);
2138
2139                 int dh2= (dh>>11) + (dh<<21);
2140                 int d= dh2 + dl;
2141
2142                 int b= d&0x7F;
2143                 int r= (d>>11)&0x7F;
2144                 int g= d>>21;
2145                 dstU[i]= ((2*RU*r + GU*g + 2*BU*b)>>(RGB2YUV_SHIFT+2-2)) + 128;
2146                 dstV[i]= ((2*RV*r + GV*g + 2*BV*b)>>(RGB2YUV_SHIFT+2-2)) + 128;
2147         }
2148 }
2149
2150 static inline void RENAME(bgr15ToY)(uint8_t *dst, uint8_t *src, int width)
2151 {
2152         int i;
2153         for(i=0; i<width; i++)
2154         {
2155                 int d= ((uint16_t*)src)[i];
2156                 int b= d&0x1F;
2157                 int g= (d>>5)&0x1F;
2158                 int r= (d>>10)&0x1F;
2159
2160                 dst[i]= ((RY*r + GY*g + BY*b)>>(RGB2YUV_SHIFT-3)) + 16;
2161         }
2162 }
2163
2164 static inline void RENAME(bgr15ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
2165 {
2166         int i;
2167         for(i=0; i<width; i++)
2168         {
2169                 int d0= ((uint32_t*)src1)[i];
2170                 int d1= ((uint32_t*)src2)[i];
2171                 
2172                 int dl= (d0&0x03E07C1F) + (d1&0x03E07C1F);
2173                 int dh= ((d0>>5)&0x03E0F81F) + ((d1>>5)&0x03E0F81F);
2174
2175                 int dh2= (dh>>11) + (dh<<21);
2176                 int d= dh2 + dl;
2177
2178                 int b= d&0x7F;
2179                 int r= (d>>10)&0x7F;
2180                 int g= d>>21;
2181                 dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2-3)) + 128;
2182                 dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2-3)) + 128;
2183         }
2184 }
2185
2186
2187 static inline void RENAME(rgb32ToY)(uint8_t *dst, uint8_t *src, int width)
2188 {
2189         int i;
2190         for(i=0; i<width; i++)
2191         {
2192                 int r=  ((uint32_t*)src)[i]&0xFF;
2193                 int g= (((uint32_t*)src)[i]>>8)&0xFF;
2194                 int b= (((uint32_t*)src)[i]>>16)&0xFF;
2195
2196                 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
2197         }
2198 }
2199
2200 static inline void RENAME(rgb32ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
2201 {
2202         int i;
2203         for(i=0; i<width; i++)
2204         {
2205                 const int a= ((uint32_t*)src1)[2*i+0];
2206                 const int e= ((uint32_t*)src1)[2*i+1];
2207                 const int c= ((uint32_t*)src2)[2*i+0];
2208                 const int d= ((uint32_t*)src2)[2*i+1];
2209                 const int l= (a&0xFF00FF) + (e&0xFF00FF) + (c&0xFF00FF) + (d&0xFF00FF);
2210                 const int h= (a&0x00FF00) + (e&0x00FF00) + (c&0x00FF00) + (d&0x00FF00);
2211                 const int r=  l&0x3FF;
2212                 const int g=  h>>8;
2213                 const int b=  l>>16;
2214
2215                 dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
2216                 dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
2217         }
2218 }
2219
2220 static inline void RENAME(rgb24ToY)(uint8_t *dst, uint8_t *src, int width)
2221 {
2222         int i;
2223         for(i=0; i<width; i++)
2224         {
2225                 int r= src[i*3+0];
2226                 int g= src[i*3+1];
2227                 int b= src[i*3+2];
2228
2229                 dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);
2230         }
2231 }
2232
2233 static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
2234 {
2235         int i;
2236         for(i=0; i<width; i++)
2237         {
2238                 int r= src1[6*i + 0] + src1[6*i + 3] + src2[6*i + 0] + src2[6*i + 3];
2239                 int g= src1[6*i + 1] + src1[6*i + 4] + src2[6*i + 1] + src2[6*i + 4];
2240                 int b= src1[6*i + 2] + src1[6*i + 5] + src2[6*i + 2] + src2[6*i + 5];
2241
2242                 dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+2)) + 128;
2243                 dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+2)) + 128;
2244         }
2245 }
2246
2247
2248 // Bilinear / Bicubic scaling
2249 static inline void RENAME(hScale)(int16_t *dst, int dstW, uint8_t *src, int srcW, int xInc,
2250                                   int16_t *filter, int16_t *filterPos, long filterSize)
2251 {
2252 #ifdef HAVE_MMX
2253         assert(filterSize % 4 == 0 && filterSize>0);
2254         if(filterSize==4) // allways true for upscaling, sometimes for down too
2255         {
2256                 long counter= -2*dstW;
2257                 filter-= counter*2;
2258                 filterPos-= counter/2;
2259                 dst-= counter/2;
2260                 asm volatile(
2261 #if defined(PIC)
2262                         "push %%"REG_b"                 \n\t"
2263 #endif
2264                         "pxor %%mm7, %%mm7              \n\t"
2265                         "movq "MANGLE(w02)", %%mm6      \n\t"
2266                         "push %%"REG_BP"                \n\t" // we use 7 regs here ...
2267                         "mov %%"REG_a", %%"REG_BP"      \n\t"
2268                         ASMALIGN(4)
2269                         "1:                             \n\t"
2270                         "movzwl (%2, %%"REG_BP"), %%eax \n\t"
2271                         "movzwl 2(%2, %%"REG_BP"), %%ebx\n\t"
2272                         "movq (%1, %%"REG_BP", 4), %%mm1\n\t"
2273                         "movq 8(%1, %%"REG_BP", 4), %%mm3\n\t"
2274                         "movd (%3, %%"REG_a"), %%mm0    \n\t"
2275                         "movd (%3, %%"REG_b"), %%mm2    \n\t"
2276                         "punpcklbw %%mm7, %%mm0         \n\t"
2277                         "punpcklbw %%mm7, %%mm2         \n\t"
2278                         "pmaddwd %%mm1, %%mm0           \n\t"
2279                         "pmaddwd %%mm2, %%mm3           \n\t"
2280                         "psrad $8, %%mm0                \n\t"
2281                         "psrad $8, %%mm3                \n\t"
2282                         "packssdw %%mm3, %%mm0          \n\t"
2283                         "pmaddwd %%mm6, %%mm0           \n\t"
2284                         "packssdw %%mm0, %%mm0          \n\t"
2285                         "movd %%mm0, (%4, %%"REG_BP")   \n\t"
2286                         "add $4, %%"REG_BP"             \n\t"
2287                         " jnc 1b                        \n\t"
2288
2289                         "pop %%"REG_BP"                 \n\t"
2290 #if defined(PIC)
2291                         "pop %%"REG_b"                  \n\t"
2292 #endif
2293                         : "+a" (counter)
2294                         : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)
2295 #if !defined(PIC)
2296                         : "%"REG_b
2297 #endif
2298                 );
2299         }
2300         else if(filterSize==8)
2301         {
2302                 long counter= -2*dstW;
2303                 filter-= counter*4;
2304                 filterPos-= counter/2;
2305                 dst-= counter/2;
2306                 asm volatile(
2307 #if defined(PIC)
2308                         "push %%"REG_b"                 \n\t"
2309 #endif
2310                         "pxor %%mm7, %%mm7              \n\t"
2311                         "movq "MANGLE(w02)", %%mm6      \n\t"
2312                         "push %%"REG_BP"                \n\t" // we use 7 regs here ...
2313                         "mov %%"REG_a", %%"REG_BP"      \n\t"
2314                         ASMALIGN(4)
2315                         "1:                             \n\t"
2316                         "movzwl (%2, %%"REG_BP"), %%eax \n\t"
2317                         "movzwl 2(%2, %%"REG_BP"), %%ebx\n\t"
2318                         "movq (%1, %%"REG_BP", 8), %%mm1\n\t"
2319                         "movq 16(%1, %%"REG_BP", 8), %%mm3\n\t"
2320                         "movd (%3, %%"REG_a"), %%mm0    \n\t"
2321                         "movd (%3, %%"REG_b"), %%mm2    \n\t"
2322                         "punpcklbw %%mm7, %%mm0         \n\t"
2323                         "punpcklbw %%mm7, %%mm2         \n\t"
2324                         "pmaddwd %%mm1, %%mm0           \n\t"
2325                         "pmaddwd %%mm2, %%mm3           \n\t"
2326
2327                         "movq 8(%1, %%"REG_BP", 8), %%mm1\n\t"
2328                         "movq 24(%1, %%"REG_BP", 8), %%mm5\n\t"
2329                         "movd 4(%3, %%"REG_a"), %%mm4   \n\t"
2330                         "movd 4(%3, %%"REG_b"), %%mm2   \n\t"
2331                         "punpcklbw %%mm7, %%mm4         \n\t"
2332                         "punpcklbw %%mm7, %%mm2         \n\t"
2333                         "pmaddwd %%mm1, %%mm4           \n\t"
2334                         "pmaddwd %%mm2, %%mm5           \n\t"
2335                         "paddd %%mm4, %%mm0             \n\t"
2336                         "paddd %%mm5, %%mm3             \n\t"
2337                                                 
2338                         "psrad $8, %%mm0                \n\t"
2339                         "psrad $8, %%mm3                \n\t"
2340                         "packssdw %%mm3, %%mm0          \n\t"
2341                         "pmaddwd %%mm6, %%mm0           \n\t"
2342                         "packssdw %%mm0, %%mm0          \n\t"
2343                         "movd %%mm0, (%4, %%"REG_BP")   \n\t"
2344                         "add $4, %%"REG_BP"             \n\t"
2345                         " jnc 1b                        \n\t"
2346
2347                         "pop %%"REG_BP"                 \n\t"
2348 #if defined(PIC)
2349                         "pop %%"REG_b"                  \n\t"
2350 #endif
2351                         : "+a" (counter)
2352                         : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)
2353 #if !defined(PIC)
2354                         : "%"REG_b
2355 #endif
2356                 );
2357         }
2358         else
2359         {
2360                 uint8_t *offset = src+filterSize;
2361                 long counter= -2*dstW;
2362 //              filter-= counter*filterSize/2;
2363                 filterPos-= counter/2;
2364                 dst-= counter/2;
2365                 asm volatile(
2366                         "pxor %%mm7, %%mm7              \n\t"
2367                         "movq "MANGLE(w02)", %%mm6      \n\t"
2368                         ASMALIGN(4)
2369                         "1:                             \n\t"
2370                         "mov %2, %%"REG_c"              \n\t"
2371                         "movzwl (%%"REG_c", %0), %%eax  \n\t"
2372                         "movzwl 2(%%"REG_c", %0), %%edx \n\t"
2373                         "mov %5, %%"REG_c"              \n\t"
2374                         "pxor %%mm4, %%mm4              \n\t"
2375                         "pxor %%mm5, %%mm5              \n\t"
2376                         "2:                             \n\t"
2377                         "movq (%1), %%mm1               \n\t"
2378                         "movq (%1, %6), %%mm3           \n\t"
2379                         "movd (%%"REG_c", %%"REG_a"), %%mm0\n\t"
2380                         "movd (%%"REG_c", %%"REG_d"), %%mm2\n\t"
2381                         "punpcklbw %%mm7, %%mm0         \n\t"
2382                         "punpcklbw %%mm7, %%mm2         \n\t"
2383                         "pmaddwd %%mm1, %%mm0           \n\t"
2384                         "pmaddwd %%mm2, %%mm3           \n\t"
2385                         "paddd %%mm3, %%mm5             \n\t"
2386                         "paddd %%mm0, %%mm4             \n\t"
2387                         "add $8, %1                     \n\t"
2388                         "add $4, %%"REG_c"              \n\t"
2389                         "cmp %4, %%"REG_c"              \n\t"
2390                         " jb 2b                         \n\t"
2391                         "add %6, %1                     \n\t"
2392                         "psrad $8, %%mm4                \n\t"
2393                         "psrad $8, %%mm5                \n\t"
2394                         "packssdw %%mm5, %%mm4          \n\t"
2395                         "pmaddwd %%mm6, %%mm4           \n\t"
2396                         "packssdw %%mm4, %%mm4          \n\t"
2397                         "mov %3, %%"REG_a"              \n\t"
2398                         "movd %%mm4, (%%"REG_a", %0)    \n\t"
2399                         "add $4, %0                     \n\t"
2400                         " jnc 1b                        \n\t"
2401
2402                         : "+r" (counter), "+r" (filter)
2403                         : "m" (filterPos), "m" (dst), "m"(offset),
2404                           "m" (src), "r" (filterSize*2)
2405                         : "%"REG_a, "%"REG_c, "%"REG_d
2406                 );
2407         }
2408 #else
2409 #ifdef HAVE_ALTIVEC
2410         hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize);
2411 #else
2412         int i;
2413         for(i=0; i<dstW; i++)
2414         {
2415                 int j;
2416                 int srcPos= filterPos[i];
2417                 int val=0;
2418 //              printf("filterPos: %d\n", filterPos[i]);
2419                 for(j=0; j<filterSize; j++)
2420                 {
2421 //                      printf("filter: %d, src: %d\n", filter[i], src[srcPos + j]);
2422                         val += ((int)src[srcPos + j])*filter[filterSize*i + j];
2423                 }
2424 //              filter += hFilterSize;
2425                 dst[i] = FFMIN(FFMAX(0, val>>7), (1<<15)-1); // the cubic equation does overflow ...
2426 //              dst[i] = val>>7;
2427         }
2428 #endif
2429 #endif
2430 }
2431       // *** horizontal scale Y line to temp buffer
2432 static inline void RENAME(hyscale)(uint16_t *dst, long dstWidth, uint8_t *src, int srcW, int xInc,
2433                                    int flags, int canMMX2BeUsed, int16_t *hLumFilter,
2434                                    int16_t *hLumFilterPos, int hLumFilterSize, void *funnyYCode, 
2435                                    int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,
2436                                    int32_t *mmx2FilterPos)
2437 {
2438     if(srcFormat==PIX_FMT_YUYV422)
2439     {
2440         RENAME(yuy2ToY)(formatConvBuffer, src, srcW);
2441         src= formatConvBuffer;
2442     }
2443     else if(srcFormat==PIX_FMT_UYVY422)
2444     {
2445         RENAME(uyvyToY)(formatConvBuffer, src, srcW);
2446         src= formatConvBuffer;
2447     }
2448     else if(srcFormat==PIX_FMT_RGB32)
2449     {
2450         RENAME(bgr32ToY)(formatConvBuffer, src, srcW);
2451         src= formatConvBuffer;
2452     }
2453     else if(srcFormat==PIX_FMT_BGR24)
2454     {
2455         RENAME(bgr24ToY)(formatConvBuffer, src, srcW);
2456         src= formatConvBuffer;
2457     }
2458     else if(srcFormat==PIX_FMT_BGR565)
2459     {
2460         RENAME(bgr16ToY)(formatConvBuffer, src, srcW);
2461         src= formatConvBuffer;
2462     }
2463     else if(srcFormat==PIX_FMT_BGR555)
2464     {
2465         RENAME(bgr15ToY)(formatConvBuffer, src, srcW);
2466         src= formatConvBuffer;
2467     }
2468     else if(srcFormat==PIX_FMT_BGR32)
2469     {
2470         RENAME(rgb32ToY)(formatConvBuffer, src, srcW);
2471         src= formatConvBuffer;
2472     }
2473     else if(srcFormat==PIX_FMT_RGB24)
2474     {
2475         RENAME(rgb24ToY)(formatConvBuffer, src, srcW);
2476         src= formatConvBuffer;
2477     }
2478
2479 #ifdef HAVE_MMX
2480         // use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one)
2481     if(!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))
2482 #else
2483     if(!(flags&SWS_FAST_BILINEAR))
2484 #endif
2485     {
2486         RENAME(hScale)(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
2487     }
2488     else // Fast Bilinear upscale / crap downscale
2489     {
2490 #if defined(ARCH_X86) || defined(ARCH_X86_64)
2491 #ifdef HAVE_MMX2
2492         int i;
2493 #if defined(PIC)
2494         uint64_t ebxsave __attribute__((aligned(8)));
2495 #endif
2496         if(canMMX2BeUsed)
2497         {
2498                 asm volatile(
2499 #if defined(PIC)
2500                         "mov %%"REG_b", %5    \n\t"
2501 #endif
2502                         "pxor %%mm7, %%mm7              \n\t"
2503                         "mov %0, %%"REG_c"              \n\t"
2504                         "mov %1, %%"REG_D"              \n\t"
2505                         "mov %2, %%"REG_d"              \n\t"
2506                         "mov %3, %%"REG_b"              \n\t"
2507                         "xor %%"REG_a", %%"REG_a"       \n\t" // i
2508                         PREFETCH" (%%"REG_c")           \n\t"
2509                         PREFETCH" 32(%%"REG_c")         \n\t"
2510                         PREFETCH" 64(%%"REG_c")         \n\t"
2511
2512 #ifdef ARCH_X86_64
2513
2514 #define FUNNY_Y_CODE \
2515                         "movl (%%"REG_b"), %%esi        \n\t"\
2516                         "call *%4                       \n\t"\
2517                         "movl (%%"REG_b", %%"REG_a"), %%esi\n\t"\
2518                         "add %%"REG_S", %%"REG_c"       \n\t"\
2519                         "add %%"REG_a", %%"REG_D"       \n\t"\
2520                         "xor %%"REG_a", %%"REG_a"       \n\t"\
2521
2522 #else
2523
2524 #define FUNNY_Y_CODE \
2525                         "movl (%%"REG_b"), %%esi        \n\t"\
2526                         "call *%4                       \n\t"\
2527                         "addl (%%"REG_b", %%"REG_a"), %%"REG_c"\n\t"\
2528                         "add %%"REG_a", %%"REG_D"       \n\t"\
2529                         "xor %%"REG_a", %%"REG_a"       \n\t"\
2530
2531 #endif
2532
2533 FUNNY_Y_CODE
2534 FUNNY_Y_CODE
2535 FUNNY_Y_CODE
2536 FUNNY_Y_CODE
2537 FUNNY_Y_CODE
2538 FUNNY_Y_CODE
2539 FUNNY_Y_CODE
2540 FUNNY_Y_CODE
2541
2542 #if defined(PIC)
2543                         "mov %5, %%"REG_b"    \n\t"
2544 #endif
2545                         :: "m" (src), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),
2546                         "m" (funnyYCode)
2547 #if defined(PIC)
2548                         ,"m" (ebxsave)
2549 #endif
2550                         : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D
2551 #if !defined(PIC)
2552                         ,"%"REG_b
2553 #endif
2554                 );
2555                 for(i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128;
2556         }
2557         else
2558         {
2559 #endif
2560         long xInc_shr16 = xInc >> 16;
2561         uint16_t xInc_mask = xInc & 0xffff;
2562         //NO MMX just normal asm ...
2563         asm volatile(
2564                 "xor %%"REG_a", %%"REG_a"       \n\t" // i
2565                 "xor %%"REG_d", %%"REG_d"       \n\t" // xx
2566                 "xorl %%ecx, %%ecx              \n\t" // 2*xalpha
2567                 ASMALIGN(4)
2568                 "1:                             \n\t"
2569                 "movzbl  (%0, %%"REG_d"), %%edi \n\t" //src[xx]
2570                 "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1]
2571                 "subl %%edi, %%esi              \n\t" //src[xx+1] - src[xx]
2572                 "imull %%ecx, %%esi             \n\t" //(src[xx+1] - src[xx])*2*xalpha
2573                 "shll $16, %%edi                \n\t"
2574                 "addl %%edi, %%esi              \n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)
2575                 "mov %1, %%"REG_D"              \n\t"
2576                 "shrl $9, %%esi                 \n\t"
2577                 "movw %%si, (%%"REG_D", %%"REG_a", 2)\n\t"
2578                 "addw %4, %%cx                  \n\t" //2*xalpha += xInc&0xFF
2579                 "adc %3, %%"REG_d"              \n\t" //xx+= xInc>>8 + carry
2580
2581                 "movzbl (%0, %%"REG_d"), %%edi  \n\t" //src[xx]
2582                 "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1]
2583                 "subl %%edi, %%esi              \n\t" //src[xx+1] - src[xx]
2584                 "imull %%ecx, %%esi             \n\t" //(src[xx+1] - src[xx])*2*xalpha
2585                 "shll $16, %%edi                \n\t"
2586                 "addl %%edi, %%esi              \n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)
2587                 "mov %1, %%"REG_D"              \n\t"
2588                 "shrl $9, %%esi                 \n\t"
2589                 "movw %%si, 2(%%"REG_D", %%"REG_a", 2)\n\t"
2590                 "addw %4, %%cx                  \n\t" //2*xalpha += xInc&0xFF
2591                 "adc %3, %%"REG_d"              \n\t" //xx+= xInc>>8 + carry
2592
2593
2594                 "add $2, %%"REG_a"              \n\t"
2595                 "cmp %2, %%"REG_a"              \n\t"
2596                 " jb 1b                         \n\t"
2597
2598
2599                 :: "r" (src), "m" (dst), "m" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask)
2600                 : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"
2601                 );
2602 #ifdef HAVE_MMX2
2603         } //if MMX2 can't be used
2604 #endif
2605 #else
2606         int i;
2607         unsigned int xpos=0;
2608         for(i=0;i<dstWidth;i++)
2609         {
2610                 register unsigned int xx=xpos>>16;
2611                 register unsigned int xalpha=(xpos&0xFFFF)>>9;
2612                 dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
2613                 xpos+=xInc;
2614         }
2615 #endif
2616     }
2617 }
2618
2619 inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, uint8_t *src2,
2620                                    int srcW, int xInc, int flags, int canMMX2BeUsed, int16_t *hChrFilter,
2621                                    int16_t *hChrFilterPos, int hChrFilterSize, void *funnyUVCode,
2622                                    int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,
2623                                    int32_t *mmx2FilterPos)
2624 {
2625     if(srcFormat==PIX_FMT_YUYV422)
2626     {
2627         RENAME(yuy2ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2628         src1= formatConvBuffer;
2629         src2= formatConvBuffer+2048;
2630     }
2631     else if(srcFormat==PIX_FMT_UYVY422)
2632     {
2633         RENAME(uyvyToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2634         src1= formatConvBuffer;
2635         src2= formatConvBuffer+2048;
2636     }
2637     else if(srcFormat==PIX_FMT_RGB32)
2638     {
2639         RENAME(bgr32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2640         src1= formatConvBuffer;
2641         src2= formatConvBuffer+2048;
2642     }
2643     else if(srcFormat==PIX_FMT_BGR24)
2644     {
2645         RENAME(bgr24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2646         src1= formatConvBuffer;
2647         src2= formatConvBuffer+2048;
2648     }
2649     else if(srcFormat==PIX_FMT_BGR565)
2650     {
2651         RENAME(bgr16ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2652         src1= formatConvBuffer;
2653         src2= formatConvBuffer+2048;
2654     }
2655     else if(srcFormat==PIX_FMT_BGR555)
2656     {
2657         RENAME(bgr15ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2658         src1= formatConvBuffer;
2659         src2= formatConvBuffer+2048;
2660     }
2661     else if(srcFormat==PIX_FMT_BGR32)
2662     {
2663         RENAME(rgb32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2664         src1= formatConvBuffer;
2665         src2= formatConvBuffer+2048;
2666     }
2667     else if(srcFormat==PIX_FMT_RGB24)
2668     {
2669         RENAME(rgb24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
2670         src1= formatConvBuffer;
2671         src2= formatConvBuffer+2048;
2672     }
2673     else if(isGray(srcFormat))
2674     {
2675         return;
2676     }
2677
2678 #ifdef HAVE_MMX
2679         // use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one)
2680     if(!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))
2681 #else
2682     if(!(flags&SWS_FAST_BILINEAR))
2683 #endif
2684     {
2685         RENAME(hScale)(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
2686         RENAME(hScale)(dst+2048, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
2687     }
2688     else // Fast Bilinear upscale / crap downscale
2689     {
2690 #if defined(ARCH_X86) || defined(ARCH_X86_64)
2691 #ifdef HAVE_MMX2
2692         int i;
2693 #if defined(PIC)
2694         uint64_t ebxsave __attribute__((aligned(8)));
2695 #endif
2696         if(canMMX2BeUsed)
2697         {
2698                 asm volatile(
2699 #if defined(PIC)
2700                         "mov %%"REG_b", %6    \n\t"
2701 #endif
2702                         "pxor %%mm7, %%mm7              \n\t"
2703                         "mov %0, %%"REG_c"              \n\t"
2704                         "mov %1, %%"REG_D"              \n\t"
2705                         "mov %2, %%"REG_d"              \n\t"
2706                         "mov %3, %%"REG_b"              \n\t"
2707                         "xor %%"REG_a", %%"REG_a"       \n\t" // i
2708                         PREFETCH" (%%"REG_c")           \n\t"
2709                         PREFETCH" 32(%%"REG_c")         \n\t"
2710                         PREFETCH" 64(%%"REG_c")         \n\t"
2711
2712 #ifdef ARCH_X86_64
2713
2714 #define FUNNY_UV_CODE \
2715                         "movl (%%"REG_b"), %%esi        \n\t"\