Statistics
| Branch: | Revision:

ffmpeg / libswscale / ppc / swscale_template.c @ b6cad3df

History | View | Annotate | Download (37.9 KB)

1
/*
2
 * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
3
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * Libav is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with Libav; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

    
21

    
22
#if COMPILE_TEMPLATE_ALTIVEC
23
#include "swscale_altivec_template.c"
24
#endif
25

    
26
static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
27
                                    const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc,
28
                                    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW)
29
{
30
#if COMPILE_TEMPLATE_ALTIVEC
31
    yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize,
32
                          chrFilter, chrSrc, chrFilterSize,
33
                          dest, uDest, vDest, dstW, chrDstW);
34
#else //COMPILE_TEMPLATE_ALTIVEC
35
    yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,
36
                chrFilter, chrSrc, chrFilterSize,
37
                alpSrc, dest, uDest, vDest, aDest, dstW, chrDstW);
38
#endif //!COMPILE_TEMPLATE_ALTIVEC
39
}
40

    
41
static inline void RENAME(yuv2nv12X)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
42
                                     const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
43
                                     uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, enum PixelFormat dstFormat)
44
{
45
    yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize,
46
                 chrFilter, chrSrc, chrFilterSize,
47
                 dest, uDest, dstW, chrDstW, dstFormat);
48
}
49

    
50
static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc,
51
                                    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW)
52
{
53
    int i;
54
    for (i=0; i<dstW; i++) {
55
        int val= (lumSrc[i]+64)>>7;
56

    
57
        if (val&256) {
58
            if (val<0) val=0;
59
            else       val=255;
60
        }
61

    
62
        dest[i]= val;
63
    }
64

    
65
    if (uDest)
66
        for (i=0; i<chrDstW; i++) {
67
            int u=(chrSrc[i       ]+64)>>7;
68
            int v=(chrSrc[i + VOFW]+64)>>7;
69

    
70
            if ((u|v)&256) {
71
                if (u<0)        u=0;
72
                else if (u>255) u=255;
73
                if (v<0)        v=0;
74
                else if (v>255) v=255;
75
            }
76

    
77
            uDest[i]= u;
78
            vDest[i]= v;
79
        }
80

    
81
    if (CONFIG_SWSCALE_ALPHA && aDest)
82
        for (i=0; i<dstW; i++) {
83
            int val= (alpSrc[i]+64)>>7;
84
            aDest[i]= av_clip_uint8(val);
85
        }
86
}
87

    
88

    
89
/**
90
 * vertical scale YV12 to RGB
91
 */
92
static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
93
                                       const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
94
                                       const int16_t **alpSrc, uint8_t *dest, long dstW, long dstY)
95
{
96
#if COMPILE_TEMPLATE_ALTIVEC
97
    /* The following list of supported dstFormat values should
98
       match what's found in the body of ff_yuv2packedX_altivec() */
99
    if (!(c->flags & SWS_BITEXACT) && !c->alpPixBuf &&
100
         (c->dstFormat==PIX_FMT_ABGR  || c->dstFormat==PIX_FMT_BGRA  ||
101
          c->dstFormat==PIX_FMT_BGR24 || c->dstFormat==PIX_FMT_RGB24 ||
102
          c->dstFormat==PIX_FMT_RGBA  || c->dstFormat==PIX_FMT_ARGB))
103
            ff_yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize,
104
                                   chrFilter, chrSrc, chrFilterSize,
105
                                   dest, dstW, dstY);
106
    else
107
#endif
108
        yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,
109
                       chrFilter, chrSrc, chrFilterSize,
110
                       alpSrc, dest, dstW, dstY);
111
}
112

    
113
/**
114
 * vertical bilinear scale YV12 to RGB
115
 */
116
static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, const uint16_t *buf1, const uint16_t *uvbuf0, const uint16_t *uvbuf1,
117
                          const uint16_t *abuf0, const uint16_t *abuf1, uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
118
{
119
    int  yalpha1=4095- yalpha;
120
    int uvalpha1=4095-uvalpha;
121
    int i;
122

    
123
    YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C(void,0), YSCALE_YUV_2_GRAY16_2_C, YSCALE_YUV_2_MONO2_C)
124
}
125

    
126
/**
127
 * YV12 to RGB without scaling or interpolating
128
 */
129
static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1,
130
                          const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y)
131
{
132
    const int yalpha1=0;
133
    int i;
134

    
135
    const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
136
    const int yalpha= 4096; //FIXME ...
137

    
138
    if (flags&SWS_FULL_CHR_H_INT) {
139
        c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y);
140
        return;
141
    }
142

    
143
    if (uvalpha < 2048) {
144
        YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C)
145
    } else {
146
        YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C)
147
    }
148
}
149

    
150
//FIXME yuy2* can read up to 7 samples too much
151

    
152
static inline void RENAME(yuy2ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
153
{
154
    int i;
155
    for (i=0; i<width; i++)
156
        dst[i]= src[2*i];
157
}
158

    
159
static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
160
{
161
    int i;
162
    for (i=0; i<width; i++) {
163
        dstU[i]= src1[4*i + 1];
164
        dstV[i]= src1[4*i + 3];
165
    }
166
    assert(src1 == src2);
167
}
168

    
169
static inline void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
170
{
171
    int i;
172
    for (i=0; i<width; i++) {
173
        dstU[i]= src1[2*i + 1];
174
        dstV[i]= src2[2*i + 1];
175
    }
176
}
177

    
178
/* This is almost identical to the previous, end exists only because
179
 * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
180
static inline void RENAME(uyvyToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
181
{
182
    int i;
183
    for (i=0; i<width; i++)
184
        dst[i]= src[2*i+1];
185
}
186

    
187
static inline void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
188
{
189
    int i;
190
    for (i=0; i<width; i++) {
191
        dstU[i]= src1[4*i + 0];
192
        dstV[i]= src1[4*i + 2];
193
    }
194
    assert(src1 == src2);
195
}
196

    
197
static inline void RENAME(BEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
198
{
199
    int i;
200
    for (i=0; i<width; i++) {
201
        dstU[i]= src1[2*i];
202
        dstV[i]= src2[2*i];
203
    }
204
}
205

    
206
static inline void RENAME(nvXXtoUV)(uint8_t *dst1, uint8_t *dst2,
207
                                    const uint8_t *src, long width)
208
{
209
    int i;
210
    for (i = 0; i < width; i++) {
211
        dst1[i] = src[2*i+0];
212
        dst2[i] = src[2*i+1];
213
    }
214
}
215

    
216
static inline void RENAME(nv12ToUV)(uint8_t *dstU, uint8_t *dstV,
217
                                    const uint8_t *src1, const uint8_t *src2,
218
                                    long width, uint32_t *unused)
219
{
220
    RENAME(nvXXtoUV)(dstU, dstV, src1, width);
221
}
222

    
223
static inline void RENAME(nv21ToUV)(uint8_t *dstU, uint8_t *dstV,
224
                                    const uint8_t *src1, const uint8_t *src2,
225
                                    long width, uint32_t *unused)
226
{
227
    RENAME(nvXXtoUV)(dstV, dstU, src1, width);
228
}
229

    
230

    
231
static inline void RENAME(bgr24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
232
{
233
    int i;
234
    for (i=0; i<width; i++) {
235
        int b= src[i*3+0];
236
        int g= src[i*3+1];
237
        int r= src[i*3+2];
238

    
239
        dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
240
    }
241
}
242

    
243
static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
244
{
245
    int i;
246
    for (i=0; i<width; i++) {
247
        int b= src1[3*i + 0];
248
        int g= src1[3*i + 1];
249
        int r= src1[3*i + 2];
250

    
251
        dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
252
        dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
253
    }
254
    assert(src1 == src2);
255
}
256

    
257
static inline void RENAME(bgr24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
258
{
259
    int i;
260
    for (i=0; i<width; i++) {
261
        int b= src1[6*i + 0] + src1[6*i + 3];
262
        int g= src1[6*i + 1] + src1[6*i + 4];
263
        int r= src1[6*i + 2] + src1[6*i + 5];
264

    
265
        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
266
        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
267
    }
268
    assert(src1 == src2);
269
}
270

    
271
static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
272
{
273
    int i;
274
    for (i=0; i<width; i++) {
275
        int r= src[i*3+0];
276
        int g= src[i*3+1];
277
        int b= src[i*3+2];
278

    
279
        dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
280
    }
281
}
282

    
283
static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
284
{
285
    int i;
286
    assert(src1==src2);
287
    for (i=0; i<width; i++) {
288
        int r= src1[3*i + 0];
289
        int g= src1[3*i + 1];
290
        int b= src1[3*i + 2];
291

    
292
        dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
293
        dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
294
    }
295
}
296

    
297
static inline void RENAME(rgb24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
298
{
299
    int i;
300
    assert(src1==src2);
301
    for (i=0; i<width; i++) {
302
        int r= src1[6*i + 0] + src1[6*i + 3];
303
        int g= src1[6*i + 1] + src1[6*i + 4];
304
        int b= src1[6*i + 2] + src1[6*i + 5];
305

    
306
        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
307
        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
308
    }
309
}
310

    
311

    
312
// bilinear / bicubic scaling
313
static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc,
314
                                  const int16_t *filter, const int16_t *filterPos, long filterSize)
315
{
316
#if COMPILE_TEMPLATE_ALTIVEC
317
    hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize);
318
#else
319
    int i;
320
    for (i=0; i<dstW; i++) {
321
        int j;
322
        int srcPos= filterPos[i];
323
        int val=0;
324
        //printf("filterPos: %d\n", filterPos[i]);
325
        for (j=0; j<filterSize; j++) {
326
            //printf("filter: %d, src: %d\n", filter[i], src[srcPos + j]);
327
            val += ((int)src[srcPos + j])*filter[filterSize*i + j];
328
        }
329
        //filter += hFilterSize;
330
        dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
331
        //dst[i] = val>>7;
332
    }
333
#endif /* COMPILE_TEMPLATE_ALTIVEC */
334
}
335

    
336
//FIXME all pal and rgb srcFormats could do this convertion as well
337
//FIXME all scalers more complex than bilinear could do half of this transform
338
static void RENAME(chrRangeToJpeg)(uint16_t *dst, int width)
339
{
340
    int i;
341
    for (i = 0; i < width; i++) {
342
        dst[i     ] = (FFMIN(dst[i     ],30775)*4663 - 9289992)>>12; //-264
343
        dst[i+VOFW] = (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264
344
    }
345
}
346
static void RENAME(chrRangeFromJpeg)(uint16_t *dst, int width)
347
{
348
    int i;
349
    for (i = 0; i < width; i++) {
350
        dst[i     ] = (dst[i     ]*1799 + 4081085)>>11; //1469
351
        dst[i+VOFW] = (dst[i+VOFW]*1799 + 4081085)>>11; //1469
352
    }
353
}
354
static void RENAME(lumRangeToJpeg)(uint16_t *dst, int width)
355
{
356
    int i;
357
    for (i = 0; i < width; i++)
358
        dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
359
}
360
static void RENAME(lumRangeFromJpeg)(uint16_t *dst, int width)
361
{
362
    int i;
363
    for (i = 0; i < width; i++)
364
        dst[i] = (dst[i]*14071 + 33561947)>>14;
365
}
366

    
367
static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,
368
                                        long dstWidth, const uint8_t *src, int srcW,
369
                                        int xInc)
370
{
371
    int i;
372
    unsigned int xpos=0;
373
    for (i=0;i<dstWidth;i++) {
374
        register unsigned int xx=xpos>>16;
375
        register unsigned int xalpha=(xpos&0xFFFF)>>9;
376
        dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
377
        xpos+=xInc;
378
    }
379
}
380

    
381
      // *** horizontal scale Y line to temp buffer
382
static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src, int srcW, int xInc,
383
                                   const int16_t *hLumFilter,
384
                                   const int16_t *hLumFilterPos, int hLumFilterSize,
385
                                   uint8_t *formatConvBuffer,
386
                                   uint32_t *pal, int isAlpha)
387
{
388
    void (*toYV12)(uint8_t *, const uint8_t *, long, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
389
    void (*convertRange)(uint16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
390

    
391
    src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset;
392

    
393
    if (toYV12) {
394
        toYV12(formatConvBuffer, src, srcW, pal);
395
        src= formatConvBuffer;
396
    }
397

    
398
    if (!c->hyscale_fast) {
399
        c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
400
    } else { // fast bilinear upscale / crap downscale
401
        c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
402
    }
403

    
404
    if (convertRange)
405
        convertRange(dst, dstWidth);
406
}
407

    
408
static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
409
                                        long dstWidth, const uint8_t *src1,
410
                                        const uint8_t *src2, int srcW, int xInc)
411
{
412
    int i;
413
    unsigned int xpos=0;
414
    for (i=0;i<dstWidth;i++) {
415
        register unsigned int xx=xpos>>16;
416
        register unsigned int xalpha=(xpos&0xFFFF)>>9;
417
        dst[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
418
        dst[i+VOFW]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
419
        /* slower
420
        dst[i]= (src1[xx]<<7) + (src1[xx+1] - src1[xx])*xalpha;
421
        dst[i+VOFW]=(src2[xx]<<7) + (src2[xx+1] - src2[xx])*xalpha;
422
        */
423
        xpos+=xInc;
424
    }
425
}
426

    
427
inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2,
428
                                   int srcW, int xInc, const int16_t *hChrFilter,
429
                                   const int16_t *hChrFilterPos, int hChrFilterSize,
430
                                   uint8_t *formatConvBuffer,
431
                                   uint32_t *pal)
432
{
433

    
434
    src1 += c->chrSrcOffset;
435
    src2 += c->chrSrcOffset;
436

    
437
    if (c->chrToYV12) {
438
        c->chrToYV12(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal);
439
        src1= formatConvBuffer;
440
        src2= formatConvBuffer+VOFW;
441
    }
442

    
443
    if (!c->hcscale_fast) {
444
        c->hScale(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
445
        c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
446
    } else { // fast bilinear upscale / crap downscale
447
        c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc);
448
    }
449

    
450
    if (c->chrConvertRange)
451
        c->chrConvertRange(dst, dstWidth);
452
}
453

    
454
#define DEBUG_SWSCALE_BUFFERS 0
455
#define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
456

    
457
static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
458
                           int srcSliceH, uint8_t* dst[], int dstStride[])
459
{
460
    /* load a few things into local vars to make the code more readable? and faster */
461
    const int srcW= c->srcW;
462
    const int dstW= c->dstW;
463
    const int dstH= c->dstH;
464
    const int chrDstW= c->chrDstW;
465
    const int chrSrcW= c->chrSrcW;
466
    const int lumXInc= c->lumXInc;
467
    const int chrXInc= c->chrXInc;
468
    const enum PixelFormat dstFormat= c->dstFormat;
469
    const int flags= c->flags;
470
    int16_t *vLumFilterPos= c->vLumFilterPos;
471
    int16_t *vChrFilterPos= c->vChrFilterPos;
472
    int16_t *hLumFilterPos= c->hLumFilterPos;
473
    int16_t *hChrFilterPos= c->hChrFilterPos;
474
    int16_t *vLumFilter= c->vLumFilter;
475
    int16_t *vChrFilter= c->vChrFilter;
476
    int16_t *hLumFilter= c->hLumFilter;
477
    int16_t *hChrFilter= c->hChrFilter;
478
    int32_t *lumMmxFilter= c->lumMmxFilter;
479
    int32_t *chrMmxFilter= c->chrMmxFilter;
480
    int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
481
    const int vLumFilterSize= c->vLumFilterSize;
482
    const int vChrFilterSize= c->vChrFilterSize;
483
    const int hLumFilterSize= c->hLumFilterSize;
484
    const int hChrFilterSize= c->hChrFilterSize;
485
    int16_t **lumPixBuf= c->lumPixBuf;
486
    int16_t **chrPixBuf= c->chrPixBuf;
487
    int16_t **alpPixBuf= c->alpPixBuf;
488
    const int vLumBufSize= c->vLumBufSize;
489
    const int vChrBufSize= c->vChrBufSize;
490
    uint8_t *formatConvBuffer= c->formatConvBuffer;
491
    const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
492
    const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
493
    int lastDstY;
494
    uint32_t *pal=c->pal_yuv;
495

    
496
    /* vars which will change and which we need to store back in the context */
497
    int dstY= c->dstY;
498
    int lumBufIndex= c->lumBufIndex;
499
    int chrBufIndex= c->chrBufIndex;
500
    int lastInLumBuf= c->lastInLumBuf;
501
    int lastInChrBuf= c->lastInChrBuf;
502

    
503
    if (isPacked(c->srcFormat)) {
504
        src[0]=
505
        src[1]=
506
        src[2]=
507
        src[3]= src[0];
508
        srcStride[0]=
509
        srcStride[1]=
510
        srcStride[2]=
511
        srcStride[3]= srcStride[0];
512
    }
513
    srcStride[1]<<= c->vChrDrop;
514
    srcStride[2]<<= c->vChrDrop;
515

    
516
    DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
517
                  src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
518
                  dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
519
    DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
520
                   srcSliceY,    srcSliceH,    dstY,    dstH);
521
    DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
522
                   vLumFilterSize,    vLumBufSize,    vChrFilterSize,    vChrBufSize);
523

    
524
    if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
525
        static int warnedAlready=0; //FIXME move this into the context perhaps
526
        if (flags & SWS_PRINT_INFO && !warnedAlready) {
527
            av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
528
                   "         ->cannot do aligned memory accesses anymore\n");
529
            warnedAlready=1;
530
        }
531
    }
532

    
533
    /* Note the user might start scaling the picture in the middle so this
534
       will not get executed. This is not really intended but works
535
       currently, so people might do it. */
536
    if (srcSliceY ==0) {
537
        lumBufIndex=-1;
538
        chrBufIndex=-1;
539
        dstY=0;
540
        lastInLumBuf= -1;
541
        lastInChrBuf= -1;
542
    }
543

    
544
    lastDstY= dstY;
545

    
546
    for (;dstY < dstH; dstY++) {
547
        unsigned char *dest =dst[0]+dstStride[0]*dstY;
548
        const int chrDstY= dstY>>c->chrDstVSubSample;
549
        unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
550
        unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
551
        unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
552

    
553
        const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
554
        const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
555
        const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
556
        int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
557
        int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
558
        int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
559
        int enough_lines;
560

    
561
        //handle holes (FAST_BILINEAR & weird filters)
562
        if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
563
        if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
564
        assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
565
        assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
566

    
567
        DEBUG_BUFFERS("dstY: %d\n", dstY);
568
        DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
569
                         firstLumSrcY,    lastLumSrcY,    lastInLumBuf);
570
        DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
571
                         firstChrSrcY,    lastChrSrcY,    lastInChrBuf);
572

    
573
        // Do we have enough lines in this slice to output the dstY line
574
        enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
575

    
576
        if (!enough_lines) {
577
            lastLumSrcY = srcSliceY + srcSliceH - 1;
578
            lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
579
            DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
580
                                            lastLumSrcY, lastChrSrcY);
581
        }
582

    
583
        //Do horizontal scaling
584
        while(lastInLumBuf < lastLumSrcY) {
585
            const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
586
            const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
587
            lumBufIndex++;
588
            assert(lumBufIndex < 2*vLumBufSize);
589
            assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
590
            assert(lastInLumBuf + 1 - srcSliceY >= 0);
591
            RENAME(hyscale)(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
592
                            hLumFilter, hLumFilterPos, hLumFilterSize,
593
                            formatConvBuffer,
594
                            pal, 0);
595
            if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
596
                RENAME(hyscale)(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW, lumXInc,
597
                                hLumFilter, hLumFilterPos, hLumFilterSize,
598
                                formatConvBuffer,
599
                                pal, 1);
600
            lastInLumBuf++;
601
            DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
602
                               lumBufIndex,    lastInLumBuf);
603
        }
604
        while(lastInChrBuf < lastChrSrcY) {
605
            const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
606
            const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
607
            chrBufIndex++;
608
            assert(chrBufIndex < 2*vChrBufSize);
609
            assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
610
            assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
611
            //FIXME replace parameters through context struct (some at least)
612

    
613
            if (c->needs_hcscale)
614
                RENAME(hcscale)(c, chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc,
615
                                hChrFilter, hChrFilterPos, hChrFilterSize,
616
                                formatConvBuffer,
617
                                pal);
618
            lastInChrBuf++;
619
            DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
620
                               chrBufIndex,    lastInChrBuf);
621
        }
622
        //wrap buf index around to stay inside the ring buffer
623
        if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
624
        if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
625
        if (!enough_lines)
626
            break; //we can't output a dstY line so let's try with the next slice
627

    
628
        if (dstY < dstH-2) {
629
            const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
630
            const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
631
            const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
632
            if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
633
                const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
634
                if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
635
                c->yuv2nv12X(c,
636
                             vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
637
                             vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
638
                             dest, uDest, dstW, chrDstW, dstFormat);
639
            } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
640
                const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
641
                if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
642
                if (is16BPS(dstFormat)) {
643
                    yuv2yuvX16inC(
644
                                  vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
645
                                  vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
646
                                  alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
647
                                  dstFormat);
648
                } else if (vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
649
                    const int16_t *lumBuf = lumSrcPtr[0];
650
                    const int16_t *chrBuf= chrSrcPtr[0];
651
                    const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
652
                    c->yuv2yuv1(c, lumBuf, chrBuf, alpBuf, dest, uDest, vDest, aDest, dstW, chrDstW);
653
                } else { //General YV12
654
                    c->yuv2yuvX(c,
655
                                vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
656
                                vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
657
                                alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
658
                }
659
            } else {
660
                assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
661
                assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);
662
                if (vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
663
                    int chrAlpha= vChrFilter[2*dstY+1];
664
                    if(flags & SWS_FULL_CHR_H_INT) {
665
                        yuv2rgbXinC_full(c, //FIXME write a packed1_full function
666
                                         vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
667
                                         vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
668
                                         alpSrcPtr, dest, dstW, dstY);
669
                    } else {
670
                        c->yuv2packed1(c, *lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1),
671
                                       alpPixBuf ? *alpSrcPtr : NULL,
672
                                       dest, dstW, chrAlpha, dstFormat, flags, dstY);
673
                    }
674
                } else if (vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
675
                    int lumAlpha= vLumFilter[2*dstY+1];
676
                    int chrAlpha= vChrFilter[2*dstY+1];
677
                    lumMmxFilter[2]=
678
                    lumMmxFilter[3]= vLumFilter[2*dstY   ]*0x10001;
679
                    chrMmxFilter[2]=
680
                    chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
681
                    if(flags & SWS_FULL_CHR_H_INT) {
682
                        yuv2rgbXinC_full(c, //FIXME write a packed2_full function
683
                                         vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
684
                                         vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
685
                                         alpSrcPtr, dest, dstW, dstY);
686
                    } else {
687
                        c->yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1),
688
                                       alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
689
                                       dest, dstW, lumAlpha, chrAlpha, dstY);
690
                    }
691
                } else { //general RGB
692
                    if(flags & SWS_FULL_CHR_H_INT) {
693
                        yuv2rgbXinC_full(c,
694
                                         vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
695
                                         vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
696
                                         alpSrcPtr, dest, dstW, dstY);
697
                    } else {
698
                        c->yuv2packedX(c,
699
                                       vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
700
                                       vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
701
                                       alpSrcPtr, dest, dstW, dstY);
702
                    }
703
                }
704
            }
705
        } else { // hmm looks like we can't use MMX here without overwriting this array's tail
706
            const int16_t **lumSrcPtr= (const int16_t **)lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
707
            const int16_t **chrSrcPtr= (const int16_t **)chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
708
            const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
709
            if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
710
                const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
711
                if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
712
                yuv2nv12XinC(
713
                             vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
714
                             vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
715
                             dest, uDest, dstW, chrDstW, dstFormat);
716
            } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12
717
                const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
718
                if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
719
                if (is16BPS(dstFormat)) {
720
                    yuv2yuvX16inC(
721
                                  vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
722
                                  vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
723
                                  alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
724
                                  dstFormat);
725
                } else {
726
                    yuv2yuvXinC(
727
                                vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
728
                                vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
729
                                alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
730
                }
731
            } else {
732
                assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
733
                assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);
734
                if(flags & SWS_FULL_CHR_H_INT) {
735
                    yuv2rgbXinC_full(c,
736
                                     vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
737
                                     vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
738
                                     alpSrcPtr, dest, dstW, dstY);
739
                } else {
740
                    yuv2packedXinC(c,
741
                                   vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
742
                                   vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
743
                                   alpSrcPtr, dest, dstW, dstY);
744
                }
745
            }
746
        }
747
    }
748

    
749
    if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
750
        fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
751

    
752
    /* store changed local vars back in the context */
753
    c->dstY= dstY;
754
    c->lumBufIndex= lumBufIndex;
755
    c->chrBufIndex= chrBufIndex;
756
    c->lastInLumBuf= lastInLumBuf;
757
    c->lastInChrBuf= lastInChrBuf;
758

    
759
    return dstY - lastDstY;
760
}
761

    
762
static void RENAME(sws_init_swScale)(SwsContext *c)
763
{
764
    enum PixelFormat srcFormat = c->srcFormat;
765

    
766
    c->yuv2nv12X    = RENAME(yuv2nv12X   );
767
    c->yuv2yuv1     = RENAME(yuv2yuv1    );
768
    c->yuv2yuvX     = RENAME(yuv2yuvX    );
769
    c->yuv2packed1  = RENAME(yuv2packed1 );
770
    c->yuv2packed2  = RENAME(yuv2packed2 );
771
    c->yuv2packedX  = RENAME(yuv2packedX );
772

    
773
    c->hScale       = RENAME(hScale      );
774

    
775
    if (c->flags & SWS_FAST_BILINEAR)
776
    {
777
        c->hyscale_fast = RENAME(hyscale_fast);
778
        c->hcscale_fast = RENAME(hcscale_fast);
779
    }
780

    
781
    c->chrToYV12 = NULL;
782
    switch(srcFormat) {
783
        case PIX_FMT_YUYV422  : c->chrToYV12 = RENAME(yuy2ToUV); break;
784
        case PIX_FMT_UYVY422  : c->chrToYV12 = RENAME(uyvyToUV); break;
785
        case PIX_FMT_NV12     : c->chrToYV12 = RENAME(nv12ToUV); break;
786
        case PIX_FMT_NV21     : c->chrToYV12 = RENAME(nv21ToUV); break;
787
        case PIX_FMT_RGB8     :
788
        case PIX_FMT_BGR8     :
789
        case PIX_FMT_PAL8     :
790
        case PIX_FMT_BGR4_BYTE:
791
        case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV; break;
792
        case PIX_FMT_YUV420P16BE:
793
        case PIX_FMT_YUV422P16BE:
794
        case PIX_FMT_YUV444P16BE: c->chrToYV12 = RENAME(BEToUV); break;
795
        case PIX_FMT_YUV420P16LE:
796
        case PIX_FMT_YUV422P16LE:
797
        case PIX_FMT_YUV444P16LE: c->chrToYV12 = RENAME(LEToUV); break;
798
    }
799
    if (c->chrSrcHSubSample) {
800
        switch(srcFormat) {
801
        case PIX_FMT_RGB48BE:
802
        case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48ToUV_half; break;
803
        case PIX_FMT_RGB32  : c->chrToYV12 = bgr32ToUV_half;  break;
804
        case PIX_FMT_RGB32_1: c->chrToYV12 = bgr321ToUV_half; break;
805
        case PIX_FMT_BGR24  : c->chrToYV12 = RENAME(bgr24ToUV_half); break;
806
        case PIX_FMT_BGR565 : c->chrToYV12 = bgr16ToUV_half; break;
807
        case PIX_FMT_BGR555 : c->chrToYV12 = bgr15ToUV_half; break;
808
        case PIX_FMT_BGR32  : c->chrToYV12 = rgb32ToUV_half;  break;
809
        case PIX_FMT_BGR32_1: c->chrToYV12 = rgb321ToUV_half; break;
810
        case PIX_FMT_RGB24  : c->chrToYV12 = RENAME(rgb24ToUV_half); break;
811
        case PIX_FMT_RGB565 : c->chrToYV12 = rgb16ToUV_half; break;
812
        case PIX_FMT_RGB555 : c->chrToYV12 = rgb15ToUV_half; break;
813
        }
814
    } else {
815
        switch(srcFormat) {
816
        case PIX_FMT_RGB48BE:
817
        case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48ToUV; break;
818
        case PIX_FMT_RGB32  : c->chrToYV12 = bgr32ToUV;  break;
819
        case PIX_FMT_RGB32_1: c->chrToYV12 = bgr321ToUV; break;
820
        case PIX_FMT_BGR24  : c->chrToYV12 = RENAME(bgr24ToUV); break;
821
        case PIX_FMT_BGR565 : c->chrToYV12 = bgr16ToUV; break;
822
        case PIX_FMT_BGR555 : c->chrToYV12 = bgr15ToUV; break;
823
        case PIX_FMT_BGR32  : c->chrToYV12 = rgb32ToUV;  break;
824
        case PIX_FMT_BGR32_1: c->chrToYV12 = rgb321ToUV; break;
825
        case PIX_FMT_RGB24  : c->chrToYV12 = RENAME(rgb24ToUV); break;
826
        case PIX_FMT_RGB565 : c->chrToYV12 = rgb16ToUV; break;
827
        case PIX_FMT_RGB555 : c->chrToYV12 = rgb15ToUV; break;
828
        }
829
    }
830

    
831
    c->lumToYV12 = NULL;
832
    c->alpToYV12 = NULL;
833
    switch (srcFormat) {
834
    case PIX_FMT_YUYV422  :
835
    case PIX_FMT_YUV420P16BE:
836
    case PIX_FMT_YUV422P16BE:
837
    case PIX_FMT_YUV444P16BE:
838
    case PIX_FMT_Y400A    :
839
    case PIX_FMT_GRAY16BE : c->lumToYV12 = RENAME(yuy2ToY); break;
840
    case PIX_FMT_UYVY422  :
841
    case PIX_FMT_YUV420P16LE:
842
    case PIX_FMT_YUV422P16LE:
843
    case PIX_FMT_YUV444P16LE:
844
    case PIX_FMT_GRAY16LE : c->lumToYV12 = RENAME(uyvyToY); break;
845
    case PIX_FMT_BGR24    : c->lumToYV12 = RENAME(bgr24ToY); break;
846
    case PIX_FMT_BGR565   : c->lumToYV12 = bgr16ToY; break;
847
    case PIX_FMT_BGR555   : c->lumToYV12 = bgr15ToY; break;
848
    case PIX_FMT_RGB24    : c->lumToYV12 = RENAME(rgb24ToY); break;
849
    case PIX_FMT_RGB565   : c->lumToYV12 = rgb16ToY; break;
850
    case PIX_FMT_RGB555   : c->lumToYV12 = rgb15ToY; break;
851
    case PIX_FMT_RGB8     :
852
    case PIX_FMT_BGR8     :
853
    case PIX_FMT_PAL8     :
854
    case PIX_FMT_BGR4_BYTE:
855
    case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY; break;
856
    case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y; break;
857
    case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y; break;
858
    case PIX_FMT_RGB32  : c->lumToYV12 = bgr32ToY;  break;
859
    case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY; break;
860
    case PIX_FMT_BGR32  : c->lumToYV12 = rgb32ToY;  break;
861
    case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY; break;
862
    case PIX_FMT_RGB48BE:
863
    case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48ToY; break;
864
    }
865
    if (c->alpPixBuf) {
866
        switch (srcFormat) {
867
        case PIX_FMT_RGB32  :
868
        case PIX_FMT_RGB32_1:
869
        case PIX_FMT_BGR32  :
870
        case PIX_FMT_BGR32_1: c->alpToYV12 = abgrToA; break;
871
        case PIX_FMT_Y400A  : c->alpToYV12 = RENAME(yuy2ToY); break;
872
        }
873
    }
874

    
875
    switch (srcFormat) {
876
    case PIX_FMT_Y400A  :
877
        c->alpSrcOffset = 1;
878
        break;
879
    case PIX_FMT_RGB32  :
880
    case PIX_FMT_BGR32  :
881
        c->alpSrcOffset = 3;
882
        break;
883
    case PIX_FMT_RGB48LE:
884
        c->lumSrcOffset = 1;
885
        c->chrSrcOffset = 1;
886
        c->alpSrcOffset = 1;
887
        break;
888
    }
889

    
890
    if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
891
        if (c->srcRange) {
892
            c->lumConvertRange = RENAME(lumRangeFromJpeg);
893
            c->chrConvertRange = RENAME(chrRangeFromJpeg);
894
        } else {
895
            c->lumConvertRange = RENAME(lumRangeToJpeg);
896
            c->chrConvertRange = RENAME(chrRangeToJpeg);
897
        }
898
    }
899

    
900
    if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
901
          srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE))
902
        c->needs_hcscale = 1;
903
}