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
|
17
|
24 #ifdef USE_FASTMEMCPY
|
|
25 #include "fastmemcpy.h"
|
|
26 #endif
|
0
|
27 /* XXX: totally non optimized */
|
|
28
|
|
29 static 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
|
|
59 static 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
|
|
122 static 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
|
|
185 int 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 }
|