Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ af27aea9

History | View | Annotate | Download (28.8 KB)

1 de6d9b64 Fabrice Bellard
/*
2
 * Misc image convertion routines
3 ff4ec49e Fabrice Bellard
 * Copyright (c) 2001, 2002 Fabrice Bellard.
4 de6d9b64 Fabrice Bellard
 *
5 ff4ec49e Fabrice Bellard
 * 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 de6d9b64 Fabrice Bellard
 *
10 ff4ec49e Fabrice Bellard
 * This library is distributed in the hope that it will be useful,
11 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ff4ec49e Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14 de6d9b64 Fabrice Bellard
 *
15 ff4ec49e Fabrice Bellard
 * 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 de6d9b64 Fabrice Bellard
 */
19
#include "avcodec.h"
20 85c242d8 Fabrice Bellard
#include "dsputil.h"
21 de6d9b64 Fabrice Bellard
22 54329dd5 Nick Kurshev
#ifdef USE_FASTMEMCPY
23
#include "fastmemcpy.h"
24
#endif
25 5981f4e6 Fred
26
#ifdef HAVE_MMX
27
#include "i386/mmx.h"
28
#endif
29 de6d9b64 Fabrice Bellard
/* XXX: totally non optimized */
30
31
static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
32
                              UINT8 *src, int width, int height)
33
{
34
    int x, y;
35
    UINT8 *p = src;
36
37
    for(y=0;y<height;y+=2) {
38
        for(x=0;x<width;x+=2) {
39
            lum[0] = p[0];
40
            cb[0] = p[1];
41
            lum[1] = p[2];
42
            cr[0] = p[3];
43
            p += 4;
44
            lum += 2;
45
            cb++;
46
            cr++;
47
        }
48
        for(x=0;x<width;x+=2) {
49
            lum[0] = p[0];
50
            lum[1] = p[2];
51
            p += 4;
52
            lum += 2;
53
        }
54
    }
55
}
56
57
#define SCALEBITS 8
58
#define ONE_HALF  (1 << (SCALEBITS - 1))
59
#define FIX(x)                ((int) ((x) * (1L<<SCALEBITS) + 0.5))
60
61
static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
62
                              UINT8 *src, int width, int height)
63
{
64
    int wrap, wrap3, x, y;
65
    int r, g, b, r1, g1, b1;
66
    UINT8 *p;
67
68
    wrap = width;
69
    wrap3 = width * 3;
70
    p = src;
71
    for(y=0;y<height;y+=2) {
72
        for(x=0;x<width;x+=2) {
73
            r = p[0];
74
            g = p[1];
75
            b = p[2];
76
            r1 = r;
77
            g1 = g;
78
            b1 = b;
79
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
80
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
81
            r = p[3];
82
            g = p[4];
83
            b = p[5];
84
            r1 += r;
85
            g1 += g;
86
            b1 += b;
87
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
88
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
89
            p += wrap3;
90
            lum += wrap;
91
92
            r = p[0];
93
            g = p[1];
94
            b = p[2];
95
            r1 += r;
96
            g1 += g;
97
            b1 += b;
98
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
99
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
100
            r = p[3];
101
            g = p[4];
102
            b = p[5];
103
            r1 += r;
104
            g1 += g;
105
            b1 += b;
106
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
107
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
108
            
109
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
110
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
111
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
112
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
113
114
            cb++;
115
            cr++;
116
            p += -wrap3 + 2 * 3;
117
            lum += -wrap + 2;
118
        }
119
        p += wrap3;
120
        lum += wrap;
121
    }
122
}
123
124 b71472eb Philip Gladstone
static void rgba32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
125
                              UINT8 *src, int width, int height)
126
{
127
    int wrap, wrap4, x, y;
128
    int r, g, b, r1, g1, b1;
129
    UINT8 *p;
130
131
    wrap = width;
132
    wrap4 = width * 4;
133
    p = src;
134
    for(y=0;y<height;y+=2) {
135
        for(x=0;x<width;x+=2) {
136
            r = p[0];
137
            g = p[1];
138
            b = p[2];
139
            r1 = r;
140
            g1 = g;
141
            b1 = b;
142
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
143
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
144
            r = p[4];
145
            g = p[5];
146
            b = p[6];
147
            r1 += r;
148
            g1 += g;
149
            b1 += b;
150
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
151
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
152
            p += wrap4;
153
            lum += wrap;
154
155
            r = p[0];
156
            g = p[1];
157
            b = p[2];
158
            r1 += r;
159
            g1 += g;
160
            b1 += b;
161
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
162
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
163
            r = p[4];
164
            g = p[5];
165
            b = p[6];
166
            r1 += r;
167
            g1 += g;
168
            b1 += b;
169
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
170
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
171
            
172
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
173
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
174
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
175
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
176
177
            cb++;
178
            cr++;
179
            p += -wrap4 + 2 * 4;
180
            lum += -wrap + 2;
181
        }
182
        p += wrap4;
183
        lum += wrap;
184
    }
185
}
186
187 de6d9b64 Fabrice Bellard
static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
188
                              UINT8 *src, int width, int height)
189
{
190
    int wrap, wrap3, x, y;
191
    int r, g, b, r1, g1, b1;
192
    UINT8 *p;
193
194
    wrap = width;
195
    wrap3 = width * 3;
196
    p = src;
197
    for(y=0;y<height;y+=2) {
198
        for(x=0;x<width;x+=2) {
199
            b = p[0];
200
            g = p[1];
201
            r = p[2];
202
            r1 = r;
203
            g1 = g;
204
            b1 = b;
205
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
206
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
207
            b = p[3];
208
            g = p[4];
209
            r = p[5];
210
            r1 += r;
211
            g1 += g;
212
            b1 += b;
213
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
214
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
215
            p += wrap3;
216
            lum += wrap;
217
218
            b = p[0];
219
            g = p[1];
220
            r = p[2];
221
            r1 += r;
222
            g1 += g;
223
            b1 += b;
224
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
225
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
226
            b = p[3];
227
            g = p[4];
228
            r = p[5];
229
            r1 += r;
230
            g1 += g;
231
            b1 += b;
232
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
233
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
234
            
235
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
236
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
237
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
238
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
239
240
            cb++;
241
            cr++;
242
            p += -wrap3 + 2 * 3;
243
            lum += -wrap + 2;
244
        }
245
        p += wrap3;
246
        lum += wrap;
247
    }
248
}
249
250 b71472eb Philip Gladstone
static void bgra32_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
251
                              UINT8 *src, int width, int height)
252
{
253
    int wrap, wrap4, x, y;
254
    int r, g, b, r1, g1, b1;
255
    UINT8 *p;
256
257
    wrap = width;
258
    wrap4 = width * 4;
259
    p = src;
260
    for(y=0;y<height;y+=2) {
261
        for(x=0;x<width;x+=2) {
262
            b = p[0];
263
            g = p[1];
264
            r = p[2];
265
            r1 = r;
266
            g1 = g;
267
            b1 = b;
268
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
269
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
270
            b = p[4];
271
            g = p[5];
272
            r = p[6];
273
            r1 += r;
274
            g1 += g;
275
            b1 += b;
276
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
277
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
278
            p += wrap4;
279
            lum += wrap;
280
281
            b = p[0];
282
            g = p[1];
283
            r = p[2];
284
            r1 += r;
285
            g1 += g;
286
            b1 += b;
287
            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + 
288
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
289
            b = p[4];
290
            g = p[5];
291
            r = p[6];
292
            r1 += r;
293
            g1 += g;
294
            b1 += b;
295
            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + 
296
                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
297
            
298
            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + 
299
                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
300
            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - 
301
                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
302
303
            cb++;
304
            cr++;
305
            p += -wrap4 + 2 * 4;
306
            lum += -wrap + 2;
307
        }
308
        p += wrap4;
309
        lum += wrap;
310
    }
311
}
312
313 85c242d8 Fabrice Bellard
/* XXX: use generic filter ? */
314
/* 1x2 -> 1x1 */
315
static void shrink2(UINT8 *dst, int dst_wrap, 
316
                    UINT8 *src, int src_wrap,
317
                    int width, int height)
318
{
319
    int w;
320
    UINT8 *s1, *s2, *d;
321
322
    for(;height > 0; height--) {
323
        s1 = src;
324
        s2 = s1 + src_wrap;
325
        d = dst;
326
        for(w = width;w >= 4; w-=4) {
327
            d[0] = (s1[0] + s2[0]) >> 1;
328
            d[1] = (s1[1] + s2[1]) >> 1;
329
            d[2] = (s1[2] + s2[2]) >> 1;
330
            d[3] = (s1[3] + s2[3]) >> 1;
331
            s1 += 4;
332
            s2 += 4;
333
            d += 4;
334
        }
335
        for(;w > 0; w--) {
336
            d[0] = (s1[0] + s2[0]) >> 1;
337
            s1++;
338
            s2++;
339
            d++;
340
        }
341
        src += 2 * src_wrap;
342
        dst += dst_wrap;
343
    }
344
}
345
346
/* 2x2 -> 1x1 */
347
static void shrink22(UINT8 *dst, int dst_wrap, 
348
                     UINT8 *src, int src_wrap,
349
                     int width, int height)
350
{
351
    int w;
352
    UINT8 *s1, *s2, *d;
353
354
    for(;height > 0; height--) {
355
        s1 = src;
356
        s2 = s1 + src_wrap;
357
        d = dst;
358
        for(w = width;w >= 4; w-=4) {
359
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 1;
360
            d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 1;
361
            d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 1;
362
            d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 1;
363
            s1 += 8;
364
            s2 += 8;
365
            d += 4;
366
        }
367
        for(;w > 0; w--) {
368
            d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 1;
369
            s1 += 2;
370
            s2 += 2;
371
            d++;
372
        }
373
        src += 2 * src_wrap;
374
        dst += dst_wrap;
375
    }
376
}
377
378 6742d95d Fran├žois Revol
/* 1x1 -> 2x2 */
379
static void grow22(UINT8 *dst, int dst_wrap,
380
                     UINT8 *src, int src_wrap,
381
                     int width, int height)
382
{
383
    int w;
384
    UINT8 *s1, *d;
385
386
    for(;height > 0; height--) {
387
        s1 = src;
388
        d = dst;
389
        for(w = width;w >= 4; w-=4) {
390
            d[1] = d[0] = s1[0];
391
            d[3] = d[2] = s1[1];
392
            s1 += 2;
393
            d += 4;
394
        }
395
        for(;w > 0; w--) {
396
            d[0] = s1[0];
397
            s1 ++;
398
            d++;
399
        }
400
        if (height%2)
401
            src += src_wrap;
402
        dst += dst_wrap;
403
    }
404
}
405
406 789587d5 Fabrice Bellard
/* 1x2 -> 2x1. width and height are given for the source picture */
407
static void conv411(UINT8 *dst, int dst_wrap, 
408
                    UINT8 *src, int src_wrap,
409
                    int width, int height)
410
{
411
    int w, c;
412
    UINT8 *s1, *s2, *d;
413
414
    for(;height > 0; height -= 2) {
415
        s1 = src;
416
        s2 = src + src_wrap;
417
        d = dst;
418
        for(w = width;w > 0; w--) {
419
            c = (s1[0] + s2[0]) >> 1;
420
            d[0] = c;
421
            d[1] = c;
422
            s1++;
423
            s2++;
424
            d += 2;
425
        }
426
        src += src_wrap * 2;
427
        dst += dst_wrap;
428
    }
429
}
430
431 85c242d8 Fabrice Bellard
static void img_copy(UINT8 *dst, int dst_wrap, 
432
                     UINT8 *src, int src_wrap,
433
                     int width, int height)
434
{
435
    for(;height > 0; height--) {
436
        memcpy(dst, src, width);
437
        dst += dst_wrap;
438
        src += src_wrap;
439
    }
440
}
441
442
#define SCALE_BITS 10
443
444
#define C_Y  (76309 >> (16 - SCALE_BITS))
445
#define C_RV (117504 >> (16 - SCALE_BITS))
446
#define C_BU (138453 >> (16 - SCALE_BITS))
447
#define C_GU (13954 >> (16 - SCALE_BITS))
448
#define C_GV (34903 >> (16 - SCALE_BITS))
449
450
#define RGBOUT(r, g, b, y1)\
451
{\
452
    y = (y1 - 16) * C_Y;\
453
    r = cm[(y + r_add) >> SCALE_BITS];\
454
    g = cm[(y + g_add) >> SCALE_BITS];\
455
    b = cm[(y + b_add) >> SCALE_BITS];\
456
}
457
458
/* XXX: no chroma interpolating is done */
459 b71472eb Philip Gladstone
static void yuv420p_to_bgra32(AVPicture *dst, AVPicture *src, 
460
                             int width, int height)
461
{
462
    UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
463
    int w, y, cb, cr, r_add, g_add, b_add, width2;
464
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
465
466
    d = dst->data[0];
467
    y1_ptr = src->data[0];
468
    cb_ptr = src->data[1];
469
    cr_ptr = src->data[2];
470
    width2 = width >> 1;
471
    for(;height > 0; height -= 2) {
472
        d1 = d;
473
        d2 = d + dst->linesize[0];
474
        y2_ptr = y1_ptr + src->linesize[0];
475
        for(w = width2; w > 0; w --) {
476
            cb = cb_ptr[0] - 128;
477
            cr = cr_ptr[0] - 128;
478
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
479
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
480
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
481
            
482
            /* output 4 pixels */
483
            RGBOUT(d1[2], d1[1], d1[0], y1_ptr[0]);
484
            RGBOUT(d1[6], d1[5], d1[4], y1_ptr[1]);
485
            RGBOUT(d2[2], d2[1], d2[0], y2_ptr[0]);
486
            RGBOUT(d2[6], d2[5], d2[4], y2_ptr[1]);
487
488
            d1[3] = d1[7] = d2[3] = d2[7] = 255;
489
490
            d1 += 8;
491
            d2 += 8;
492
            y1_ptr += 2;
493
            y2_ptr += 2;
494
            cb_ptr++;
495
            cr_ptr++;
496
        }
497
        d += 2 * dst->linesize[0];
498
        y1_ptr += 2 * src->linesize[0] - width;
499
        cb_ptr += src->linesize[1] - width2;
500
        cr_ptr += src->linesize[2] - width2;
501
    }
502
}
503
504
/* XXX: no chroma interpolating is done */
505
static void yuv420p_to_rgba32(AVPicture *dst, AVPicture *src, 
506
                             int width, int height)
507
{
508
    UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
509
    int w, y, cb, cr, r_add, g_add, b_add, width2;
510
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
511
512
    d = dst->data[0];
513
    y1_ptr = src->data[0];
514
    cb_ptr = src->data[1];
515
    cr_ptr = src->data[2];
516
    width2 = width >> 1;
517
    for(;height > 0; height -= 2) {
518
        d1 = d;
519
        d2 = d + dst->linesize[0];
520
        y2_ptr = y1_ptr + src->linesize[0];
521
        for(w = width2; w > 0; w --) {
522
            cb = cb_ptr[0] - 128;
523
            cr = cr_ptr[0] - 128;
524
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
525
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
526
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
527
            
528
            /* output 4 pixels */
529
            RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
530
            RGBOUT(d1[4], d1[5], d1[6], y1_ptr[1]);
531
            RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]);
532
            RGBOUT(d2[4], d2[5], d2[6], y2_ptr[1]);
533
534
            d1[3] = d1[7] = d2[3] = d2[7] = 255;
535
536
            d1 += 8;
537
            d2 += 8;
538
            y1_ptr += 2;
539
            y2_ptr += 2;
540
            cb_ptr++;
541
            cr_ptr++;
542
        }
543
        d += 2 * dst->linesize[0];
544
        y1_ptr += 2 * src->linesize[0] - width;
545
        cb_ptr += src->linesize[1] - width2;
546
        cr_ptr += src->linesize[2] - width2;
547
    }
548
}
549
550
/* XXX: no chroma interpolating is done */
551 85c242d8 Fabrice Bellard
static void yuv420p_to_rgb24(AVPicture *dst, AVPicture *src, 
552
                             int width, int height)
553
{
554
    UINT8 *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr, *d, *d1, *d2;
555
    int w, y, cb, cr, r_add, g_add, b_add, width2;
556
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
557
558
    d = dst->data[0];
559
    y1_ptr = src->data[0];
560
    cb_ptr = src->data[1];
561
    cr_ptr = src->data[2];
562
    width2 = width >> 1;
563
    for(;height > 0; height -= 2) {
564
        d1 = d;
565
        d2 = d + dst->linesize[0];
566
        y2_ptr = y1_ptr + src->linesize[0];
567
        for(w = width2; w > 0; w --) {
568
            cb = cb_ptr[0] - 128;
569
            cr = cr_ptr[0] - 128;
570
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
571
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
572
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
573
            
574
            /* output 4 pixels */
575
            RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
576
            RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]);
577
            RGBOUT(d2[0], d2[1], d2[2], y2_ptr[0]);
578
            RGBOUT(d2[3], d2[4], d2[5], y2_ptr[1]);
579
580
            d1 += 6;
581
            d2 += 6;
582
            y1_ptr += 2;
583
            y2_ptr += 2;
584
            cb_ptr++;
585
            cr_ptr++;
586
        }
587
        d += 2 * dst->linesize[0];
588
        y1_ptr += 2 * src->linesize[0] - width;
589
        cb_ptr += src->linesize[1] - width2;
590
        cr_ptr += src->linesize[2] - width2;
591
    }
592
}
593
594
/* XXX: no chroma interpolating is done */
595
static void yuv422p_to_rgb24(AVPicture *dst, AVPicture *src, 
596
                             int width, int height)
597
{
598
    UINT8 *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;
599
    int w, y, cb, cr, r_add, g_add, b_add, width2;
600
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
601
602
    d = dst->data[0];
603
    y1_ptr = src->data[0];
604
    cb_ptr = src->data[1];
605
    cr_ptr = src->data[2];
606
    width2 = width >> 1;
607
    for(;height > 0; height --) {
608
        d1 = d;
609
        for(w = width2; w > 0; w --) {
610
            cb = cb_ptr[0] - 128;
611
            cr = cr_ptr[0] - 128;
612
            r_add = C_RV * cr + (1 << (SCALE_BITS - 1));
613
            g_add = - C_GU * cb - C_GV * cr + (1 << (SCALE_BITS - 1));
614
            b_add = C_BU * cb + (1 << (SCALE_BITS - 1));
615
            
616
            /* output 2 pixels */
617
            RGBOUT(d1[0], d1[1], d1[2], y1_ptr[0]);
618
            RGBOUT(d1[3], d1[4], d1[5], y1_ptr[1]);
619
620
            d1 += 6;
621
            y1_ptr += 2;
622
            cb_ptr++;
623
            cr_ptr++;
624
        }
625
        d += dst->linesize[0];
626
        y1_ptr += src->linesize[0] - width;
627
        cb_ptr += src->linesize[1] - width2;
628
        cr_ptr += src->linesize[2] - width2;
629
    }
630
}
631
632
/* XXX: always use linesize. Return -1 if not supported */
633
int img_convert(AVPicture *dst, int dst_pix_fmt,
634
                AVPicture *src, int pix_fmt, 
635
                int width, int height)
636
{
637
    int i;
638
639 bc657ac3 Zdenek Kabelac
    assert(pix_fmt != PIX_FMT_ANY && dst_pix_fmt != PIX_FMT_ANY);
640
641 85c242d8 Fabrice Bellard
    if (dst_pix_fmt == pix_fmt) {
642
        switch(pix_fmt) {
643
        case PIX_FMT_YUV420P:
644
            for(i=0;i<3;i++) {
645
                if (i == 1) {
646
                    width >>= 1;
647
                    height >>= 1;
648
                }
649
                img_copy(dst->data[i], dst->linesize[i],
650
                         src->data[i], src->linesize[i],
651
                         width, height);
652
            }
653
            break;
654
        default:
655
            return -1;
656
        }
657
    } else if (dst_pix_fmt == PIX_FMT_YUV420P) {
658
        
659
        switch(pix_fmt) {
660 789587d5 Fabrice Bellard
        case PIX_FMT_YUV411P:
661
            img_copy(dst->data[0], dst->linesize[0],
662
                     src->data[0], src->linesize[0],
663
                     width, height);
664
            conv411(dst->data[1], dst->linesize[1],
665
                    src->data[1], src->linesize[1],
666
                    width / 4, height);
667
            conv411(dst->data[2], dst->linesize[2],
668
                    src->data[2], src->linesize[2],
669
                    width / 4, height);
670
            break;
671 6742d95d Fran├žois Revol
        case PIX_FMT_YUV410P:
672
            img_copy(dst->data[0], dst->linesize[0],
673
                     src->data[0], src->linesize[0],
674
                     width, height);
675
            grow22(dst->data[1], dst->linesize[1],
676
                     src->data[1], src->linesize[1],
677
                     width/2, height/2);
678
            grow22(dst->data[2], dst->linesize[2],
679
                     src->data[2], src->linesize[2],
680
                     width/2, height/2);
681
            break;
682 85c242d8 Fabrice Bellard
        case PIX_FMT_YUV420P:
683
            for(i=0;i<3;i++) {
684
                img_copy(dst->data[i], dst->linesize[i],
685
                         src->data[i], src->linesize[i],
686
                         width, height);
687
            }
688
            break;
689
        case PIX_FMT_YUV422P:
690
            img_copy(dst->data[0], dst->linesize[0],
691
                     src->data[0], src->linesize[0],
692
                     width, height);
693
            width >>= 1;
694
            height >>= 1;
695
            for(i=1;i<3;i++) {
696
                shrink2(dst->data[i], dst->linesize[i],
697
                        src->data[i], src->linesize[i],
698
                        width, height);
699
            }
700
            break;
701
        case PIX_FMT_YUV444P:
702
            img_copy(dst->data[0], dst->linesize[0],
703
                     src->data[0], src->linesize[0],
704
                     width, height);
705
            width >>= 1;
706
            height >>= 1;
707
            for(i=1;i<3;i++) {
708
                shrink22(dst->data[i], dst->linesize[i],
709
                         src->data[i], src->linesize[i],
710
                         width, height);
711
            }
712
            break;
713
        case PIX_FMT_YUV422:
714
            yuv422_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
715
                              src->data[0], width, height);
716
            break;
717
        case PIX_FMT_RGB24:
718
            rgb24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
719
                             src->data[0], width, height);
720
            break;
721 b71472eb Philip Gladstone
        case PIX_FMT_RGBA32:
722
            rgba32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
723
                             src->data[0], width, height);
724
            break;
725 85c242d8 Fabrice Bellard
        case PIX_FMT_BGR24:
726
            bgr24_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
727
                             src->data[0], width, height);
728
            break;
729 b71472eb Philip Gladstone
        case PIX_FMT_BGRA32:
730
            bgra32_to_yuv420p(dst->data[0], dst->data[1], dst->data[2], 
731
                             src->data[0], width, height);
732
            break;
733 85c242d8 Fabrice Bellard
        default:
734
            return -1;
735
        }
736
    } else if (dst_pix_fmt == PIX_FMT_RGB24) {
737
        switch(pix_fmt) {
738
        case PIX_FMT_YUV420P:
739
            yuv420p_to_rgb24(dst, src, width, height);
740
            break;
741
        case PIX_FMT_YUV422P:
742
            yuv422p_to_rgb24(dst, src, width, height);
743 b71472eb Philip Gladstone
            break;
744
        default:
745
            return -1;
746
        }
747
    } else if (dst_pix_fmt == PIX_FMT_RGBA32) {
748
        switch(pix_fmt) {
749
        case PIX_FMT_YUV420P:
750
            yuv420p_to_rgba32(dst, src, width, height);
751
            break;
752
        default:
753
            return -1;
754
        }
755
    } else if (dst_pix_fmt == PIX_FMT_BGRA32) {
756
        switch(pix_fmt) {
757
        case PIX_FMT_YUV420P:
758
            yuv420p_to_bgra32(dst, src, width, height);
759 85c242d8 Fabrice Bellard
            break;
760
        default:
761
            return -1;
762
        }
763
    } else {
764
        return -1;
765
    }
766
    return 0;
767
}
768
769 5981f4e6 Fred
770
#ifdef HAVE_MMX
771
#define DEINT_INPLACE_LINE_LUM \
772
                    movd_m2r(lum_m4[0],mm0);\
773
                    movd_m2r(lum_m3[0],mm1);\
774
                    movd_m2r(lum_m2[0],mm2);\
775
                    movd_m2r(lum_m1[0],mm3);\
776
                    movd_m2r(lum[0],mm4);\
777
                    punpcklbw_r2r(mm7,mm0);\
778
                    movd_r2m(mm2,lum_m4[0]);\
779
                    punpcklbw_r2r(mm7,mm1);\
780
                    punpcklbw_r2r(mm7,mm2);\
781
                    punpcklbw_r2r(mm7,mm3);\
782
                    punpcklbw_r2r(mm7,mm4);\
783
                    paddw_r2r(mm3,mm1);\
784
                    psllw_i2r(1,mm2);\
785
                    paddw_r2r(mm4,mm0);\
786
                    psllw_i2r(2,mm1);\
787
                    paddw_r2r(mm6,mm2);\
788
                    paddw_r2r(mm2,mm1);\
789
                    psubusw_r2r(mm0,mm1);\
790
                    psrlw_i2r(3,mm1);\
791
                    packuswb_r2r(mm7,mm1);\
792
                    movd_r2m(mm1,lum_m2[0]);
793
794
#define DEINT_LINE_LUM \
795
                    movd_m2r(lum_m4[0],mm0);\
796
                    movd_m2r(lum_m3[0],mm1);\
797
                    movd_m2r(lum_m2[0],mm2);\
798
                    movd_m2r(lum_m1[0],mm3);\
799
                    movd_m2r(lum[0],mm4);\
800
                    punpcklbw_r2r(mm7,mm0);\
801
                    punpcklbw_r2r(mm7,mm1);\
802
                    punpcklbw_r2r(mm7,mm2);\
803
                    punpcklbw_r2r(mm7,mm3);\
804
                    punpcklbw_r2r(mm7,mm4);\
805
                    paddw_r2r(mm3,mm1);\
806
                    psllw_i2r(1,mm2);\
807
                    paddw_r2r(mm4,mm0);\
808
                    psllw_i2r(2,mm1);\
809
                    paddw_r2r(mm6,mm2);\
810
                    paddw_r2r(mm2,mm1);\
811
                    psubusw_r2r(mm0,mm1);\
812
                    psrlw_i2r(3,mm1);\
813
                    packuswb_r2r(mm7,mm1);\
814
                    movd_r2m(mm1,dst[0]);
815
#endif
816
817 85c242d8 Fabrice Bellard
/* filter parameters: [-1 4 2 4 -1] // 8 */
818 5981f4e6 Fred
static void deinterlace_line(UINT8 *dst, UINT8 *lum_m4, UINT8 *lum_m3, UINT8 *lum_m2, UINT8 *lum_m1, UINT8 *lum,
819
                                int size)
820 85c242d8 Fabrice Bellard
{
821 5981f4e6 Fred
#ifndef HAVE_MMX
822 85c242d8 Fabrice Bellard
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
823
    int sum;
824
825
    for(;size > 0;size--) {
826 5981f4e6 Fred
        sum = -lum_m4[0];
827
        sum += lum_m3[0] << 2;
828
        sum += lum_m2[0] << 1;
829
        sum += lum_m1[0] << 2;
830
        sum += -lum[0];
831 85c242d8 Fabrice Bellard
        dst[0] = cm[(sum + 4) >> 3];
832 5981f4e6 Fred
        lum_m4++;
833
        lum_m3++;
834
        lum_m2++;
835
        lum_m1++;
836
        lum++;
837 85c242d8 Fabrice Bellard
        dst++;
838
    }
839 5981f4e6 Fred
#else
840
841
    for (;size > 3; size-=4) {
842
        DEINT_LINE_LUM
843
        lum_m4+=4;
844
        lum_m3+=4;
845
        lum_m2+=4;
846
        lum_m1+=4;
847
        lum+=4;
848
        dst+=4;
849
    }
850
#endif
851
}
852
static void deinterlace_line_inplace(UINT8 *lum_m4, UINT8 *lum_m3, UINT8 *lum_m2, UINT8 *lum_m1, UINT8 *lum,
853
                             int size)
854
{
855
#ifndef HAVE_MMX
856
    UINT8 *cm = cropTbl + MAX_NEG_CROP;
857
    int sum;
858
859
    for(;size > 0;size--) {
860
        sum = -lum_m4[0];
861
        sum += lum_m3[0] << 2;
862
        sum += lum_m2[0] << 1;
863
        lum_m4[0]=lum_m2[0];
864
        sum += lum_m1[0] << 2;
865
        sum += -lum[0];
866
        lum_m2[0] = cm[(sum + 4) >> 3];
867
        lum_m4++;
868
        lum_m3++;
869
        lum_m2++;
870
        lum_m1++;
871
        lum++;
872
    }
873
#else
874
875
    for (;size > 3; size-=4) {
876
        DEINT_INPLACE_LINE_LUM
877
        lum_m4+=4;
878
        lum_m3+=4;
879
        lum_m2+=4;
880
        lum_m1+=4;
881
        lum+=4;
882
    }
883
#endif
884 85c242d8 Fabrice Bellard
}
885
886
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
887
   top field is copied as is, but the bottom field is deinterlaced
888
   against the top field. */
889
static void deinterlace_bottom_field(UINT8 *dst, int dst_wrap,
890 5981f4e6 Fred
                                    UINT8 *src1, int src_wrap,
891
                                    int width, int height)
892 85c242d8 Fabrice Bellard
{
893 5981f4e6 Fred
    UINT8 *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
894
    int y;
895
896
    src_m2 = src1;
897
    src_m1 = src1;
898
    src_0=&src_m1[src_wrap];
899
    src_p1=&src_0[src_wrap];
900
    src_p2=&src_p1[src_wrap];
901
    for(y=0;y<(height-2);y+=2) {
902
        memcpy(dst,src_m1,width);
903 85c242d8 Fabrice Bellard
        dst += dst_wrap;
904 5981f4e6 Fred
        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
905
        src_m2 = src_0;
906
        src_m1 = src_p1;
907
        src_0 = src_p2;
908
        src_p1 += 2*src_wrap;
909
        src_p2 += 2*src_wrap;
910 85c242d8 Fabrice Bellard
        dst += dst_wrap;
911
    }
912 5981f4e6 Fred
    memcpy(dst,src_m1,width);
913
    dst += dst_wrap;
914
    /* do last line */
915
    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
916
}
917
918
static void deinterlace_bottom_field_inplace(UINT8 *src1, int src_wrap,
919
                                     int width, int height)
920
{
921
    UINT8 *src_m1, *src_0, *src_p1, *src_p2;
922
    int y;
923
    UINT8 *buf;
924
    buf = (UINT8*)av_malloc(width);
925
926
    src_m1 = src1;
927
    memcpy(buf,src_m1,width);
928
    src_0=&src_m1[src_wrap];
929
    src_p1=&src_0[src_wrap];
930
    src_p2=&src_p1[src_wrap];
931
    for(y=0;y<(height-2);y+=2) {
932
        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
933
        src_m1 = src_p1;
934
        src_0 = src_p2;
935
        src_p1 += 2*src_wrap;
936
        src_p2 += 2*src_wrap;
937
    }
938
    /* do last line */
939
    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
940 6000abfa Fabrice Bellard
    av_free(buf);
941 85c242d8 Fabrice Bellard
}
942
943
944 5981f4e6 Fred
/* deinterlace - if not supported return -1 */
945 85c242d8 Fabrice Bellard
int avpicture_deinterlace(AVPicture *dst, AVPicture *src,
946 de6d9b64 Fabrice Bellard
                          int pix_fmt, int width, int height)
947
{
948 85c242d8 Fabrice Bellard
    int i;
949
950
    if (pix_fmt != PIX_FMT_YUV420P &&
951
        pix_fmt != PIX_FMT_YUV422P &&
952
        pix_fmt != PIX_FMT_YUV444P)
953
        return -1;
954 5981f4e6 Fred
    if ((width & 3) != 0 || (height & 3) != 0)
955 85c242d8 Fabrice Bellard
        return -1;
956 5981f4e6 Fred
957
#ifdef HAVE_MMX
958
    {
959
        mmx_t rounder;
960
        rounder.uw[0]=4;
961
        rounder.uw[1]=4;
962
        rounder.uw[2]=4;
963
        rounder.uw[3]=4;
964
        pxor_r2r(mm7,mm7);
965
        movq_m2r(rounder,mm6);
966
    }
967
#endif
968
969 85c242d8 Fabrice Bellard
    
970
    for(i=0;i<3;i++) {
971
        if (i == 1) {
972
            switch(pix_fmt) {
973
            case PIX_FMT_YUV420P:
974
                width >>= 1;
975
                height >>= 1;
976
                break;
977
            case PIX_FMT_YUV422P:
978
                width >>= 1;
979
                break;
980
            default:
981
                break;
982
            }
983
        }
984 5981f4e6 Fred
        if (src == dst) {
985
            deinterlace_bottom_field_inplace(src->data[i], src->linesize[i],
986 85c242d8 Fabrice Bellard
                                 width, height);
987 5981f4e6 Fred
        } else {
988
            deinterlace_bottom_field(dst->data[i],dst->linesize[i],
989
                                        src->data[i], src->linesize[i],
990
                                        width, height);
991
        }
992 de6d9b64 Fabrice Bellard
    }
993 5981f4e6 Fred
#ifdef HAVE_MMX
994
    emms();
995
#endif
996 85c242d8 Fabrice Bellard
    return 0;
997 de6d9b64 Fabrice Bellard
}
998 cd4af68a Zdenek Kabelac
999
#undef FIX