Statistics
| Branch: | Revision:

ffmpeg / libavcodec / imgconvert.c @ d771bcae

History | View | Annotate | Download (6.08 KB)

1
/*
2
 * Misc image convertion routines
3
 * Copyright (c) 2001 Gerard Lantau.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program 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
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 */
19
#include <stdlib.h>
20
#include <stdio.h>
21
#include <string.h>
22
#include "avcodec.h"
23

    
24
/* XXX: totally non optimized */
25

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

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

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

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

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

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

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

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

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

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

    
172
            cb++;
173
            cr++;
174
            p += -wrap3 + 2 * 3;
175
            lum += -wrap + 2;
176
        }
177
        p += wrap3;
178
        lum += wrap;
179
    }
180
}
181

    
182
int img_convert_to_yuv420(UINT8 *img_out, UINT8 *img, 
183
                          int pix_fmt, int width, int height)
184
{
185
    UINT8 *pict;
186
    int size, size_out;
187
    UINT8 *picture[3];
188

    
189
    pict = img_out;
190
    size = width * height;
191
    size_out = (size * 3) / 2;
192
    picture[0] = pict;
193
    picture[1] = pict + size;
194
    picture[2] = picture[1] + (size / 4);
195

    
196
    switch(pix_fmt) {
197
    case PIX_FMT_YUV420P:
198
        memcpy(pict, img, size_out);
199
        break;
200
    case PIX_FMT_YUV422:
201
        yuv422_to_yuv420p(picture[0], picture[1], picture[2], 
202
                          img, width, height);
203
        break;
204
    case PIX_FMT_RGB24:
205
        rgb24_to_yuv420p(picture[0], picture[1], picture[2], 
206
                         img, width, height);
207
        break;
208
    case PIX_FMT_BGR24:
209
        bgr24_to_yuv420p(picture[0], picture[1], picture[2], 
210
                         img, width, height);
211
        break;
212
    }
213
    return size_out;
214
}