fix msmpeg4 seek
[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
54329dd5
NK
24#ifdef USE_FASTMEMCPY
25#include "fastmemcpy.h"
26#endif
de6d9b64
FB
27/* XXX: totally non optimized */
28
29static void yuv422_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
30 UINT8 *src, int width, int height)
31{
32 int x, y;
33 UINT8 *p = src;
34
35 for(y=0;y<height;y+=2) {
36 for(x=0;x<width;x+=2) {
37 lum[0] = p[0];
38 cb[0] = p[1];
39 lum[1] = p[2];
40 cr[0] = p[3];
41 p += 4;
42 lum += 2;
43 cb++;
44 cr++;
45 }
46 for(x=0;x<width;x+=2) {
47 lum[0] = p[0];
48 lum[1] = p[2];
49 p += 4;
50 lum += 2;
51 }
52 }
53}
54
55#define SCALEBITS 8
56#define ONE_HALF (1 << (SCALEBITS - 1))
57#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
58
59static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
60 UINT8 *src, int width, int height)
61{
62 int wrap, wrap3, x, y;
63 int r, g, b, r1, g1, b1;
64 UINT8 *p;
65
66 wrap = width;
67 wrap3 = width * 3;
68 p = src;
69 for(y=0;y<height;y+=2) {
70 for(x=0;x<width;x+=2) {
71 r = p[0];
72 g = p[1];
73 b = p[2];
74 r1 = r;
75 g1 = g;
76 b1 = b;
77 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
78 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
79 r = p[3];
80 g = p[4];
81 b = p[5];
82 r1 += r;
83 g1 += g;
84 b1 += b;
85 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
86 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
87 p += wrap3;
88 lum += wrap;
89
90 r = p[0];
91 g = p[1];
92 b = p[2];
93 r1 += r;
94 g1 += g;
95 b1 += b;
96 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
97 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
98 r = p[3];
99 g = p[4];
100 b = p[5];
101 r1 += r;
102 g1 += g;
103 b1 += b;
104 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
105 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
106
107 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
108 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
109 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
110 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
111
112 cb++;
113 cr++;
114 p += -wrap3 + 2 * 3;
115 lum += -wrap + 2;
116 }
117 p += wrap3;
118 lum += wrap;
119 }
120}
121
122static void bgr24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr,
123 UINT8 *src, int width, int height)
124{
125 int wrap, wrap3, x, y;
126 int r, g, b, r1, g1, b1;
127 UINT8 *p;
128
129 wrap = width;
130 wrap3 = width * 3;
131 p = src;
132 for(y=0;y<height;y+=2) {
133 for(x=0;x<width;x+=2) {
134 b = p[0];
135 g = p[1];
136 r = p[2];
137 r1 = r;
138 g1 = g;
139 b1 = b;
140 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
141 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
142 b = p[3];
143 g = p[4];
144 r = p[5];
145 r1 += r;
146 g1 += g;
147 b1 += b;
148 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
149 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
150 p += wrap3;
151 lum += wrap;
152
153 b = p[0];
154 g = p[1];
155 r = p[2];
156 r1 += r;
157 g1 += g;
158 b1 += b;
159 lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +
160 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
161 b = p[3];
162 g = p[4];
163 r = p[5];
164 r1 += r;
165 g1 += g;
166 b1 += b;
167 lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +
168 FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
169
170 cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +
171 FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
172 cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -
173 FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
174
175 cb++;
176 cr++;
177 p += -wrap3 + 2 * 3;
178 lum += -wrap + 2;
179 }
180 p += wrap3;
181 lum += wrap;
182 }
183}
184
185int img_convert_to_yuv420(UINT8 *img_out, UINT8 *img,
186 int pix_fmt, int width, int height)
187{
188 UINT8 *pict;
189 int size, size_out;
190 UINT8 *picture[3];
191
192 pict = img_out;
193 size = width * height;
194 size_out = (size * 3) / 2;
195 picture[0] = pict;
196 picture[1] = pict + size;
197 picture[2] = picture[1] + (size / 4);
198
199 switch(pix_fmt) {
200 case PIX_FMT_YUV420P:
201 memcpy(pict, img, size_out);
202 break;
203 case PIX_FMT_YUV422:
204 yuv422_to_yuv420p(picture[0], picture[1], picture[2],
205 img, width, height);
206 break;
207 case PIX_FMT_RGB24:
208 rgb24_to_yuv420p(picture[0], picture[1], picture[2],
209 img, width, height);
210 break;
211 case PIX_FMT_BGR24:
212 bgr24_to_yuv420p(picture[0], picture[1], picture[2],
213 img, width, height);
214 break;
215 }
216 return size_out;
217}