Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ 789587d5

History | View | Annotate | Download (25.3 KB)

1
/*
2
 * Misc image convertion routines
3
 * Copyright (c) 2001, 2002 Fabrice Bellard.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
#include "avcodec.h"
20
#include "dsputil.h"
21

    
22
#ifdef USE_FASTMEMCPY
23
#include "fastmemcpy.h"
24
#endif
25
/* XXX: totally non optimized */
26

    
27
static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
28
                              UINT8 *src, int width, int height)
29
{
30
    int x, y;
31
    UINT8 *p = src;
32

    
33
    for(y=0;y<height;y+=2) {
34
        for(x=0;x<width;x+=2) {
35
            lum[0] = p[0];
36
            cb[0] = p[1];
37
            lum[1] = p[2];
38
            cr[0] = p[3];
39
            p += 4;
40
            lum += 2;
41
            cb++;
42
            cr++;
43
        }
44
        for(x=0;x<width;x+=2) {
45
            lum[0] = p[0];
46
            lum[1] = p[2];
47
            p += 4;
48
            lum += 2;
49
        }
50
    }
51
}
52

    
53
#define SCALEBITS 8
54
#define ONE_HALF  (1 << (SCALEBITS - 1))
55
#define FIX(x)                ((int) ((x) * (1L<<SCALEBITS) + 0.5))
56

    
57
static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
58
                              UINT8 *src, int width, int height)
59
{
60
    int wrap, wrap3, x, y;
61
    int r, g, b, r1, g1, b1;
62
    UINT8 *p;
63

    
64
    wrap = width;
65
    wrap3 = width * 3;
66
    p = src;
67
    for(y=0;y<height;y+=2) {
68
        for(x=0;x<width;x+=2) {
69
            r = p[0];
70
            g = p[1];
71
            b = p[2];
72
            r1 = r;
73
            g1 = g;
74
            b1 = b;
75
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
76
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
77
            r = p[3];
78
            g = p[4];
79
            b = p[5];
80
            r1 += r;
81
            g1 += g;
82
            b1 += b;
83
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
84
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
85
            p += wrap3;
86
            lum += wrap;
87

    
88
            r = p[0];
89
            g = p[1];
90
            b = p[2];
91
            r1 += r;
92
            g1 += g;
93
            b1 += b;
94
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
95
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
96
            r = p[3];
97
            g = p[4];
98
            b = p[5];
99
            r1 += r;
100
            g1 += g;
101
            b1 += b;
102
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
103
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
104
            
105
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
106
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
107
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
108
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
109

    
110
            cb++;
111
            cr++;
112
            p += -wrap3 + 2 * 3;
113
            lum += -wrap + 2;
114
        }
115
        p += wrap3;
116
        lum += wrap;
117
    }
118
}
119

    
120
static void rgba32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
121
                              UINT8 *src, int width, int height)
122
{
123
    int wrap, wrap4, x, y;
124
    int r, g, b, r1, g1, b1;
125
    UINT8 *p;
126

    
127
    wrap = width;
128
    wrap4 = width * 4;
129
    p = src;
130
    for(y=0;y<height;y+=2) {
131
        for(x=0;x<width;x+=2) {
132
            r = p[0];
133
            g = p[1];
134
            b = p[2];
135
            r1 = r;
136
            g1 = g;
137
            b1 = b;
138
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
139
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
140
            r = p[4];
141
            g = p[5];
142
            b = p[6];
143
            r1 += r;
144
            g1 += g;
145
            b1 += b;
146
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
147
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
148
            p += wrap4;
149
            lum += wrap;
150

    
151
            r = p[0];
152
            g = p[1];
153
            b = p[2];
154
            r1 += r;
155
            g1 += g;
156
            b1 += b;
157
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
158
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
159
            r = p[4];
160
            g = p[5];
161
            b = p[6];
162
            r1 += r;
163
            g1 += g;
164
            b1 += b;
165
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
166
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
167
            
168
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
169
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
170
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
171
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
172

    
173
            cb++;
174
            cr++;
175
            p += -wrap4 + 2 * 4;
176
            lum += -wrap + 2;
177
        }
178
        p += wrap4;
179
        lum += wrap;
180
    }
181
}
182

    
183
static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
184
                              UINT8 *src, int width, int height)
185
{
186
    int wrap, wrap3, x, y;
187
    int r, g, b, r1, g1, b1;
188
    UINT8 *p;
189

    
190
    wrap = width;
191
    wrap3 = width * 3;
192
    p = src;
193
    for(y=0;y<height;y+=2) {
194
        for(x=0;x<width;x+=2) {
195
            b = p[0];
196
            g = p[1];
197
            r = p[2];
198
            r1 = r;
199
            g1 = g;
200
            b1 = b;
201
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
202
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
203
            b = p[3];
204
            g = p[4];
205
            r = p[5];
206
            r1 += r;
207
            g1 += g;
208
            b1 += b;
209
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
210
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
211
            p += wrap3;
212
            lum += wrap;
213

    
214
            b = p[0];
215
            g = p[1];
216
            r = p[2];
217
            r1 += r;
218
            g1 += g;
219
            b1 += b;
220
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
221
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
222
            b = p[3];
223
            g = p[4];
224
            r = p[5];
225
            r1 += r;
226
            g1 += g;
227
            b1 += b;
228
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
229
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
230
            
231
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
232
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
233
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
234
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
235

    
236
            cb++;
237
            cr++;
238
            p += -wrap3 + 2 * 3;
239
            lum += -wrap + 2;
240
        }
241
        p += wrap3;
242
        lum += wrap;
243
    }
244
}
245

    
246
static void bgra32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
247
                              UINT8 *src, int width, int height)
248
{
249
    int wrap, wrap4, x, y;
250
    int r, g, b, r1, g1, b1;
251
    UINT8 *p;
252

    
253
    wrap = width;
254
    wrap4 = width * 4;
255
    p = src;
256
    for(y=0;y<height;y+=2) {
257
        for(x=0;x<width;x+=2) {
258
            b = p[0];
259
            g = p[1];
260
            r = p[2];
261
            r1 = r;
262
            g1 = g;
263
            b1 = b;
264
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
265
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
266
            b = p[4];
267
            g = p[5];
268
            r = p[6];
269
            r1 += r;
270
            g1 += g;
271
            b1 += b;
272
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
273
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
274
            p += wrap4;
275
            lum += wrap;
276

    
277
            b = p[0];
278
            g = p[1];
279
            r = p[2];
280
            r1 += r;
281
            g1 += g;
282
            b1 += b;
283
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
284
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
285
            b = p[4];
286
            g = p[5];
287
            r = p[6];
288
            r1 += r;
289
            g1 += g;
290
            b1 += b;
291
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
292
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
293
            
294
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
295
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
296
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
297
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
298

    
299
            cb++;
300
            cr++;
301
            p += -wrap4 + 2 * 4;
302
            lum += -wrap + 2;
303
        }
304
        p += wrap4;
305
        lum += wrap;
306
    }
307
}
308

    
309
/* XXX: use generic filter ? */
310
/* 1x2 -> 1x1 */
311
static void shrink2(UINT8 *dst, int dst_wrap, 
312
                    UINT8 *src, int src_wrap,
313
                    int width, int height)
314
{
315
    int w;
316
    UINT8 *s1, *s2, *d;
317

    
318
    for(;height > 0; height--) {
319
        s1 = src;
320
        s2 = s1 + src_wrap;
321
        d = dst;
322
        for(w = width;w >= 4; w-=4) {
323
            d[0] = (s1[0] + s2[0]) >> 1;
324
            d[1] = (s1[1] + s2[1]) >> 1;
325
            d[2] = (s1[2] + s2[2]) >> 1;
326
            d[3] = (s1[3] + s2[3]) >> 1;
327
            s1 += 4;
328
            s2 += 4;
329
            d += 4;
330
        }
331
        for(;w > 0; w--) {
332
            d[0] = (s1[0] + s2[0]) >> 1;
333
            s1++;
334
            s2++;
335
            d++;
336
        }
337
        src += 2 * src_wrap;
338
        dst += dst_wrap;
339
    }
340
}
341

    
342
/* 2x2 -> 1x1 */
343
static void shrink22(UINT8 *dst, int dst_wrap, 
344
                     UINT8 *src, int src_wrap,
345
                     int width, int height)
346
{
347
    int w;
348
    UINT8 *s1, *s2, *d;
349

    
350
    for(;height > 0; height--) {
351
        s1 = src;
352
        s2 = s1 + src_wrap;
353
        d = dst;
354
        for(w = width;w >= 4; w-=4) {
355
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 1;
356
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 1;
357
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 1;
358
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 1;
359
            s1 += 8;
360
            s2 += 8;
361
            d += 4;
362
        }
363
        for(;w > 0; w--) {
364
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 1;
365
            s1 += 2;
366
            s2 += 2;
367
            d++;
368
        }
369
        src += 2 * src_wrap;
370
        dst += dst_wrap;
371
    }
372
}
373

    
374
/* 1x1 -> 2x2 */
375
static void grow22(UINT8 *dst, int dst_wrap,
376
                     UINT8 *src, int src_wrap,
377
                     int width, int height)
378
{
379
    int w;
380
    UINT8 *s1, *d;
381

    
382
    for(;height > 0; height--) {
383
        s1 = src;
384
        d = dst;
385
        for(w = width;w >= 4; w-=4) {
386
            d[1] = d[0] = s1[0];
387
            d[3] = d[2] = s1[1];
388
            s1 += 2;
389
            d += 4;
390
        }
391
        for(;w > 0; w--) {
392
            d[0] = s1[0];
393
            s1 ++;
394
            d++;
395
        }
396
        if (height%2)
397
            src += src_wrap;
398
        dst += dst_wrap;
399
    }
400
}
401

    
402
/* 1x2 -> 2x1. width and height are given for the source picture */
403
static void conv411(UINT8 *dst, int dst_wrap, 
404
                    UINT8 *src, int src_wrap,
405
                    int width, int height)
406
{
407
    int w, c;
408
    UINT8 *s1, *s2, *d;
409

    
410
    for(;height > 0; height -= 2) {
411
        s1 = src;
412
        s2 = src + src_wrap;
413
        d = dst;
414
        for(w = width;w > 0; w--) {
415
            c = (s1[0] + s2[0]) >> 1;
416
            d[0] = c;
417
            d[1] = c;
418
            s1++;
419
            s2++;
420
            d += 2;
421
        }
422
        src += src_wrap * 2;
423
        dst += dst_wrap;
424
    }
425
}
426

    
427
static void img_copy(UINT8 *dst, int dst_wrap, 
428
                     UINT8 *src, int src_wrap,
429
                     int width, int height)
430
{
431
    for(;height > 0; height--) {
432
        memcpy(dst, src, width);
433
        dst += dst_wrap;
434
        src += src_wrap;
435
    }
436
}
437

    
438
#define SCALE_BITS 10
439

    
440
#define C_Y  (76309 >> (16 - SCALE_BITS))
441
#define C_RV (117504 >> (16 - SCALE_BITS))
442
#define C_BU (138453 >> (16 - SCALE_BITS))
443
#define C_GU (13954 >> (16 - SCALE_BITS))
444
#define C_GV (34903 >> (16 - SCALE_BITS))
445

    
446
#define RGBOUT(r, g, b, y1)\
447
{\
448
    y = (y1 - 16) * C_Y;\
449
    r = cm[(y + r_add) >> SCALE_BITS];\
450
    g = cm[(y + g_add) >> SCALE_BITS];\
451
    b = cm[(y + b_add) >> SCALE_BITS];\
452
}
453

    
454
/* XXX: no chroma interpolating is done */
455
static void yuv420p_to_bgra32(AVPicture *dst, AVPicture *src, 
456
                             int width, int height)
457
{
458
    UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
459
    int w, y, cb, cr, r_add, g_add, b_add, width2;
460
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
461

    
462
    d = dst->data[0];
463
    y1_ptr = src->data[0];
464
    cb_ptr = src->data[1];
465
    cr_ptr = src->data[2];
466
    width2 = width >> 1;
467
    for(;height > 0; height -= 2) {
468
        d1 = d;
469
        d2 = d + dst->linesize[0];
470
        y2_ptr = y1_ptr + src->linesize[0];
471
        for(w = width2; w > 0; w --) {
472
            cb = cb_ptr[0] - 128;
473
            cr = cr_ptr[0] - 128;
474
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
475
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
476
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
477
            
478
            /* output 4 pixels */
479
            RGBOUT(d1[2], d1[1], d1[0], y1_ptr[0]);
480
            RGBOUT(d1[6], d1[5], d1[4], y1_ptr[1]);
481
            RGBOUT(d2[2], d2[1], d2[0], y2_ptr[0]);
482
            RGBOUT(d2[6], d2[5], d2[4], y2_ptr[1]);
483

    
484
            d1[3] = d1[7] = d2[3] = d2[7] = 255;
485

    
486
            d1 += 8;
487
            d2 += 8;
488
            y1_ptr += 2;
489
            y2_ptr += 2;
490
            cb_ptr++;
491
            cr_ptr++;
492
        }
493
        d += 2 * dst->linesize[0];
494
        y1_ptr += 2 * src->linesize[0] - width;
495
        cb_ptr += src->linesize[1] - width2;
496
        cr_ptr += src->linesize[2] - width2;
497
    }
498
}
499

    
500
/* XXX: no chroma interpolating is done */
501
static void yuv420p_to_rgba32(AVPicture *dst, AVPicture *src, 
502
                             int width, int height)
503
{
504
    UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
505
    int w, y, cb, cr, r_add, g_add, b_add, width2;
506
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
507

    
508
    d = dst->data[0];
509
    y1_ptr = src->data[0];
510
    cb_ptr = src->data[1];
511
    cr_ptr = src->data[2];
512
    width2 = width >> 1;
513
    for(;height > 0; height -= 2) {
514
        d1 = d;
515
        d2 = d + dst->linesize[0];
516
        y2_ptr = y1_ptr + src->linesize[0];
517
        for(w = width2; w > 0; w --) {
518
            cb = cb_ptr[0] - 128;
519
            cr = cr_ptr[0] - 128;
520
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
521
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
522
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
523
            
524
            /* output 4 pixels */
525
            RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
526
            RGBOUT(d1[4], d1[5], d1[6], y1_ptr[1]);
527
            RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]);
528
            RGBOUT(d2[4], d2[5], d2[6], y2_ptr[1]);
529

    
530
            d1[3] = d1[7] = d2[3] = d2[7] = 255;
531

    
532
            d1 += 8;
533
            d2 += 8;
534
            y1_ptr += 2;
535
            y2_ptr += 2;
536
            cb_ptr++;
537
            cr_ptr++;
538
        }
539
        d += 2 * dst->linesize[0];
540
        y1_ptr += 2 * src->linesize[0] - width;
541
        cb_ptr += src->linesize[1] - width2;
542
        cr_ptr += src->linesize[2] - width2;
543
    }
544
}
545

    
546
/* XXX: no chroma interpolating is done */
547
static void yuv420p_to_rgb24(AVPicture *dst, AVPicture *src, 
548
                             int width, int height)
549
{
550
    UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
551
    int w, y, cb, cr, r_add, g_add, b_add, width2;
552
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
553

    
554
    d = dst->data[0];
555
    y1_ptr = src->data[0];
556
    cb_ptr = src->data[1];
557
    cr_ptr = src->data[2];
558
    width2 = width >> 1;
559
    for(;height > 0; height -= 2) {
560
        d1 = d;
561
        d2 = d + dst->linesize[0];
562
        y2_ptr = y1_ptr + src->linesize[0];
563
        for(w = width2; w > 0; w --) {
564
            cb = cb_ptr[0] - 128;
565
            cr = cr_ptr[0] - 128;
566
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
567
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
568
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
569
            
570
            /* output 4 pixels */
571
            RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
572
            RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]);
573
            RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]);
574
            RGBOUT(d2[3], d2[4], d2[5], y2_ptr[1]);
575

    
576
            d1 += 6;
577
            d2 += 6;
578
            y1_ptr += 2;
579
            y2_ptr += 2;
580
            cb_ptr++;
581
            cr_ptr++;
582
        }
583
        d += 2 * dst->linesize[0];
584
        y1_ptr += 2 * src->linesize[0] - width;
585
        cb_ptr += src->linesize[1] - width2;
586
        cr_ptr += src->linesize[2] - width2;
587
    }
588
}
589

    
590
/* XXX: no chroma interpolating is done */
591
static void yuv422p_to_rgb24(AVPicture *dst, AVPicture *src, 
592
                             int width, int height)
593
{
594
    UINT8 *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
595
    int w, y, cb, cr, r_add, g_add, b_add, width2;
596
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
597

    
598
    d = dst->data[0];
599
    y1_ptr = src->data[0];
600
    cb_ptr = src->data[1];
601
    cr_ptr = src->data[2];
602
    width2 = width >> 1;
603
    for(;height > 0; height --) {
604
        d1 = d;
605
        for(w = width2; w > 0; w --) {
606
            cb = cb_ptr[0] - 128;
607
            cr = cr_ptr[0] - 128;
608
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
609
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
610
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
611
            
612
            /* output 2 pixels */
613
            RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
614
            RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]);
615

    
616
            d1 += 6;
617
            y1_ptr += 2;
618
            cb_ptr++;
619
            cr_ptr++;
620
        }
621
        d += dst->linesize[0];
622
        y1_ptr += src->linesize[0] - width;
623
        cb_ptr += src->linesize[1] - width2;
624
        cr_ptr += src->linesize[2] - width2;
625
    }
626
}
627

    
628
/* XXX: always use linesize. Return -1 if not supported */
629
int img_convert(AVPicture *dst, int dst_pix_fmt,
630
                AVPicture *src, int pix_fmt, 
631
                int width, int height)
632
{
633
    int i;
634

    
635
    assert(pix_fmt != PIX_FMT_ANY && dst_pix_fmt != PIX_FMT_ANY);
636

    
637
    if (dst_pix_fmt == pix_fmt) {
638
        switch(pix_fmt) {
639
        case PIX_FMT_YUV420P:
640
            for(i=0;i<3;i++) {
641
                if (i == 1) {
642
                    width >>= 1;
643
                    height >>= 1;
644
                }
645
                img_copy(dst->data[i], dst->linesize[i],
646
                         src->data[i], src->linesize[i],
647
                         width, height);
648
            }
649
            break;
650
        default:
651
            return -1;
652
        }
653
    } else if (dst_pix_fmt == PIX_FMT_YUV420P) {
654
        
655
        switch(pix_fmt) {
656
        case PIX_FMT_YUV411P:
657
            img_copy(dst->data[0], dst->linesize[0],
658
                     src->data[0], src->linesize[0],
659
                     width, height);
660
            conv411(dst->data[1], dst->linesize[1],
661
                    src->data[1], src->linesize[1],
662
                    width / 4, height);
663
            conv411(dst->data[2], dst->linesize[2],
664
                    src->data[2], src->linesize[2],
665
                    width / 4, height);
666
            break;
667
        case PIX_FMT_YUV410P:
668
            img_copy(dst->data[0], dst->linesize[0],
669
                     src->data[0], src->linesize[0],
670
                     width, height);
671
            grow22(dst->data[1], dst->linesize[1],
672
                     src->data[1], src->linesize[1],
673
                     width/2, height/2);
674
            grow22(dst->data[2], dst->linesize[2],
675
                     src->data[2], src->linesize[2],
676
                     width/2, height/2);
677
            break;
678
        case PIX_FMT_YUV420P:
679
            for(i=0;i<3;i++) {
680
                img_copy(dst->data[i], dst->linesize[i],
681
                         src->data[i], src->linesize[i],
682
                         width, height);
683
            }
684
            break;
685
        case PIX_FMT_YUV422P:
686
            img_copy(dst->data[0], dst->linesize[0],
687
                     src->data[0], src->linesize[0],
688
                     width, height);
689
            width >>= 1;
690
            height >>= 1;
691
            for(i=1;i<3;i++) {
692
                shrink2(dst->data[i], dst->linesize[i],
693
                        src->data[i], src->linesize[i],
694
                        width, height);
695
            }
696
            break;
697
        case PIX_FMT_YUV444P:
698
            img_copy(dst->data[0], dst->linesize[0],
699
                     src->data[0], src->linesize[0],
700
                     width, height);
701
            width >>= 1;
702
            height >>= 1;
703
            for(i=1;i<3;i++) {
704
                shrink22(dst->data[i], dst->linesize[i],
705
                         src->data[i], src->linesize[i],
706
                         width, height);
707
            }
708
            break;
709
        case PIX_FMT_YUV422:
710
            yuv422_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
711
                              src->data[0], width, height);
712
            break;
713
        case PIX_FMT_RGB24:
714
            rgb24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
715
                             src->data[0], width, height);
716
            break;
717
        case PIX_FMT_RGBA32:
718
            rgba32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
719
                             src->data[0], width, height);
720
            break;
721
        case PIX_FMT_BGR24:
722
            bgr24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
723
                             src->data[0], width, height);
724
            break;
725
        case PIX_FMT_BGRA32:
726
            bgra32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
727
                             src->data[0], width, height);
728
            break;
729
        default:
730
            return -1;
731
        }
732
    } else if (dst_pix_fmt == PIX_FMT_RGB24) {
733
        switch(pix_fmt) {
734
        case PIX_FMT_YUV420P:
735
            yuv420p_to_rgb24(dst, src, width, height);
736
            break;
737
        case PIX_FMT_YUV422P:
738
            yuv422p_to_rgb24(dst, src, width, height);
739
            break;
740
        default:
741
            return -1;
742
        }
743
    } else if (dst_pix_fmt == PIX_FMT_RGBA32) {
744
        switch(pix_fmt) {
745
        case PIX_FMT_YUV420P:
746
            yuv420p_to_rgba32(dst, src, width, height);
747
            break;
748
        default:
749
            return -1;
750
        }
751
    } else if (dst_pix_fmt == PIX_FMT_BGRA32) {
752
        switch(pix_fmt) {
753
        case PIX_FMT_YUV420P:
754
            yuv420p_to_bgra32(dst, src, width, height);
755
            break;
756
        default:
757
            return -1;
758
        }
759
    } else {
760
        return -1;
761
    }
762
    return 0;
763
}
764

    
765
/* filter parameters: [-1 4 2 4 -1] // 8 */
766
static void deinterlace_line(UINT8 *dst, UINT8 *src, int src_wrap,
767
                             int size)
768
{
769
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
770
    int sum;
771
    UINT8 *s;
772

    
773
    for(;size > 0;size--) {
774
        s = src;
775
        sum = -s[0];
776
        s += src_wrap;
777
        sum += s[0] << 2;
778
        s += src_wrap;
779
        sum += s[0] << 1;
780
        s += src_wrap;
781
        sum += s[0] << 2;
782
        s += src_wrap;
783
        sum += -s[0];
784
        dst[0] = cm[(sum + 4) >> 3];
785
        dst++;
786
        src++;
787
    }
788
}
789

    
790
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
791
   top field is copied as is, but the bottom field is deinterlaced
792
   against the top field. */
793
static void deinterlace_bottom_field(UINT8 *dst, int dst_wrap,
794
                                     UINT8 *src1, int src_wrap,
795
                                     int width, int height)
796
{
797
    UINT8 *src, *ptr;
798
    int y, y1, i;
799
    UINT8 *buf;
800

    
801
    buf = (UINT8*)av_malloc(5 * width);
802

    
803
    src = src1;
804
    for(y=0;y<height;y+=2) {
805
        /* copy top field line */
806
        memcpy(dst, src, width);
807
        dst += dst_wrap;
808
        src += (1 - 2) * src_wrap;
809
        y1 = y - 2;
810
        if (y1 >= 0 && (y1 + 4) < height) {
811
            /* fast case : no edges */
812
            deinterlace_line(dst, src, src_wrap, width);
813
        } else {
814
            /* in order to use the same function, we use an intermediate buffer */
815
            ptr = buf;
816
            for(i=0;i<5;i++) {
817
                if (y1 < 0)
818
                    memcpy(ptr, src1, width);
819
                else if (y1 >= height) 
820
                    memcpy(ptr, src1 + (height - 1) * src_wrap, width);
821
                else
822
                    memcpy(ptr, src1 + y1 * src_wrap, width);
823
                y1++;
824
                ptr += width;
825
            }
826
            deinterlace_line(dst, buf, width, width);
827
        }
828
        dst += dst_wrap;
829
        src += (2 + 1) * src_wrap;
830
    }
831
    av_free(buf);
832
}
833

    
834

    
835
/* deinterlace, return -1 if format not handled */
836
int avpicture_deinterlace(AVPicture *dst, AVPicture *src,
837
                          int pix_fmt, int width, int height)
838
{
839
    int i;
840

    
841
    if (pix_fmt != PIX_FMT_YUV420P &&
842
        pix_fmt != PIX_FMT_YUV422P &&
843
        pix_fmt != PIX_FMT_YUV444P)
844
        return -1;
845
    if ((width & 1) != 0 || (height & 3) != 0)
846
        return -1;
847
    
848
    for(i=0;i<3;i++) {
849
        if (i == 1) {
850
            switch(pix_fmt) {
851
            case PIX_FMT_YUV420P:
852
                width >>= 1;
853
                height >>= 1;
854
                break;
855
            case PIX_FMT_YUV422P:
856
                width >>= 1;
857
                break;
858
            default:
859
                break;
860
            }
861
        }
862
        deinterlace_bottom_field(dst->data[i], dst->linesize[i],
863
                                 src->data[i], src->linesize[i],
864
                                 width, height);
865
    }
866
    return 0;
867
}
868

    
869
#undef FIX