0
|
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 }
|