Initial revision
[libav.git] / libavcodec / imgconvert.c
CommitLineData
de6d9b64
FB
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
26static 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
56static 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
119static 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
182int 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}