Commit | Line | Data |
---|---|---|
e76709d8 KS |
1 | /* |
2 | * software YUV to RGB converter | |
3 | * | |
4 | * Copyright (C) 2009 Konstantin Shishkov | |
5 | * | |
e76709d8 KS |
6 | * 1,4,8bpp support and context / deglobalize stuff |
7 | * by Michael Niedermayer (michaelni@gmx.at) | |
8 | * | |
9 | * This file is part of FFmpeg. | |
10 | * | |
11 | * FFmpeg is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU Lesser General Public | |
13 | * License as published by the Free Software Foundation; either | |
14 | * version 2.1 of the License, or (at your option) any later version. | |
15 | * | |
16 | * FFmpeg is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 | * Lesser General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU Lesser General Public | |
22 | * License along with FFmpeg; if not, write to the Free Software | |
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
24 | */ | |
25 | ||
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <inttypes.h> | |
29 | #include <assert.h> | |
30 | ||
31 | #include "config.h" | |
32 | #include "rgb2rgb.h" | |
33 | #include "swscale.h" | |
34 | #include "swscale_internal.h" | |
d0ce212a | 35 | #include "libavutil/x86_cpu.h" |
e76709d8 | 36 | |
e76709d8 KS |
37 | extern const uint8_t dither_8x8_32[8][8]; |
38 | extern const uint8_t dither_8x8_73[8][8]; | |
39 | extern const uint8_t dither_8x8_220[8][8]; | |
40 | ||
e76709d8 KS |
41 | const int32_t ff_yuv2rgb_coeffs[8][4] = { |
42 | {117504, 138453, 13954, 34903}, /* no sequence_display_extension */ | |
43 | {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ | |
44 | {104597, 132201, 25675, 53279}, /* unspecified */ | |
45 | {104597, 132201, 25675, 53279}, /* reserved */ | |
46 | {104448, 132798, 24759, 53109}, /* FCC */ | |
47 | {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ | |
48 | {104597, 132201, 25675, 53279}, /* SMPTE 170M */ | |
49 | {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ | |
50 | }; | |
51 | ||
52 | #define LOADCHROMA(i) \ | |
53 | U = pu[i]; \ | |
54 | V = pv[i]; \ | |
55 | r = (void *)c->table_rV[V]; \ | |
56 | g = (void *)(c->table_gU[U] + c->table_gV[V]); \ | |
57 | b = (void *)c->table_bU[U]; | |
58 | ||
59 | #define PUTRGB(dst,src,i,o) \ | |
60 | Y = src[2*i+o]; \ | |
61 | dst[2*i ] = r[Y] + g[Y] + b[Y]; \ | |
62 | Y = src[2*i+1-o]; \ | |
63 | dst[2*i+1] = r[Y] + g[Y] + b[Y]; | |
64 | ||
65 | #define PUTRGB24(dst,src,i) \ | |
66 | Y = src[2*i]; \ | |
67 | dst[6*i+0] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y]; \ | |
68 | Y = src[2*i+1]; \ | |
69 | dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y]; | |
70 | ||
71 | #define PUTBGR24(dst,src,i) \ | |
72 | Y = src[2*i]; \ | |
73 | dst[6*i+0] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y]; \ | |
74 | Y = src[2*i+1]; \ | |
75 | dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y]; | |
76 | ||
3acd545f CS |
77 | #define PUTRGBA(dst,ysrc,asrc,i,o,s) \ |
78 | Y = ysrc[2*i+o]; \ | |
79 | dst[2*i ] = r[Y] + g[Y] + b[Y] + (asrc[2*i ]<<s); \ | |
80 | Y = ysrc[2*i+1-o]; \ | |
81 | dst[2*i+1] = r[Y] + g[Y] + b[Y] + (asrc[2*i+1]<<s); | |
82 | ||
68e7f482 KS |
83 | #define PUTRGB48(dst,src,i) \ |
84 | Y = src[2*i]; \ | |
85 | dst[12*i+ 0] = dst[12*i+ 1] = r[Y]; \ | |
86 | dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \ | |
87 | dst[12*i+ 4] = dst[12*i+ 5] = b[Y]; \ | |
88 | Y = src[2*i+1]; \ | |
89 | dst[12*i+ 6] = dst[12*i+ 7] = r[Y]; \ | |
90 | dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \ | |
91 | dst[12*i+10] = dst[12*i+11] = b[Y]; | |
92 | ||
9a10a076 | 93 | #define YUV2RGBFUNC(func_name, dst_type, alpha) \ |
e76709d8 KS |
94 | static int func_name(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, \ |
95 | int srcSliceH, uint8_t* dst[], int dstStride[]){\ | |
96 | int y;\ | |
97 | \ | |
3acd545f | 98 | if (!alpha && c->srcFormat == PIX_FMT_YUV422P) {\ |
e76709d8 KS |
99 | srcStride[1] *= 2;\ |
100 | srcStride[2] *= 2;\ | |
101 | }\ | |
102 | for (y=0; y<srcSliceH; y+=2) {\ | |
103 | dst_type *dst_1 = (dst_type*)(dst[0] + (y+srcSliceY )*dstStride[0]);\ | |
104 | dst_type *dst_2 = (dst_type*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);\ | |
105 | dst_type av_unused *r, *b;\ | |
106 | dst_type *g;\ | |
107 | uint8_t *py_1 = src[0] + y*srcStride[0];\ | |
108 | uint8_t *py_2 = py_1 + srcStride[0];\ | |
109 | uint8_t *pu = src[1] + (y>>1)*srcStride[1];\ | |
110 | uint8_t *pv = src[2] + (y>>1)*srcStride[2];\ | |
3acd545f | 111 | uint8_t av_unused *pa_1, *pa_2;\ |
e76709d8 | 112 | unsigned int h_size = c->dstW>>3;\ |
3acd545f CS |
113 | if (alpha){\ |
114 | pa_1 = src[3] + y*srcStride[3];\ | |
115 | pa_2 = pa_1 + srcStride[3];\ | |
116 | }\ | |
e76709d8 KS |
117 | while (h_size--) {\ |
118 | int av_unused U, V;\ | |
119 | int Y;\ | |
120 | ||
121 | #define ENDYUV2RGBLINE(dst_delta)\ | |
122 | pu += 4;\ | |
123 | pv += 4;\ | |
124 | py_1 += 8;\ | |
125 | py_2 += 8;\ | |
126 | dst_1 += dst_delta;\ | |
127 | dst_2 += dst_delta;\ | |
128 | }\ | |
129 | if (c->dstW & 4) {\ | |
130 | int av_unused Y, U, V;\ | |
131 | ||
132 | #define ENDYUV2RGBFUNC()\ | |
133 | }\ | |
134 | }\ | |
135 | return srcSliceH;\ | |
136 | } | |
137 | ||
138 | #define CLOSEYUV2RGBFUNC(dst_delta)\ | |
139 | ENDYUV2RGBLINE(dst_delta)\ | |
140 | ENDYUV2RGBFUNC() | |
141 | ||
68e7f482 KS |
142 | YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0) |
143 | LOADCHROMA(0); | |
144 | PUTRGB48(dst_1,py_1,0); | |
145 | PUTRGB48(dst_2,py_2,0); | |
146 | ||
147 | LOADCHROMA(1); | |
148 | PUTRGB48(dst_2,py_2,1); | |
149 | PUTRGB48(dst_1,py_1,1); | |
150 | ||
151 | LOADCHROMA(2); | |
152 | PUTRGB48(dst_1,py_1,2); | |
153 | PUTRGB48(dst_2,py_2,2); | |
154 | ||
155 | LOADCHROMA(3); | |
156 | PUTRGB48(dst_2,py_2,3); | |
157 | PUTRGB48(dst_1,py_1,3); | |
158 | ENDYUV2RGBLINE(48) | |
159 | LOADCHROMA(0); | |
160 | PUTRGB48(dst_1,py_1,0); | |
161 | PUTRGB48(dst_2,py_2,0); | |
162 | ||
163 | LOADCHROMA(1); | |
164 | PUTRGB48(dst_2,py_2,1); | |
165 | PUTRGB48(dst_1,py_1,1); | |
166 | ENDYUV2RGBFUNC() | |
167 | ||
9a10a076 | 168 | YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0) |
e76709d8 KS |
169 | LOADCHROMA(0); |
170 | PUTRGB(dst_1,py_1,0,0); | |
171 | PUTRGB(dst_2,py_2,0,1); | |
172 | ||
173 | LOADCHROMA(1); | |
174 | PUTRGB(dst_2,py_2,1,1); | |
175 | PUTRGB(dst_1,py_1,1,0); | |
e76709d8 KS |
176 | |
177 | LOADCHROMA(2); | |
178 | PUTRGB(dst_1,py_1,2,0); | |
179 | PUTRGB(dst_2,py_2,2,1); | |
180 | ||
181 | LOADCHROMA(3); | |
182 | PUTRGB(dst_2,py_2,3,1); | |
183 | PUTRGB(dst_1,py_1,3,0); | |
184 | ENDYUV2RGBLINE(8) | |
185 | LOADCHROMA(0); | |
186 | PUTRGB(dst_1,py_1,0,0); | |
187 | PUTRGB(dst_2,py_2,0,1); | |
188 | ||
189 | LOADCHROMA(1); | |
190 | PUTRGB(dst_2,py_2,1,1); | |
191 | PUTRGB(dst_1,py_1,1,0); | |
192 | ENDYUV2RGBFUNC() | |
193 | ||
3acd545f CS |
194 | YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1) |
195 | LOADCHROMA(0); | |
196 | PUTRGBA(dst_1,py_1,pa_1,0,0,24); | |
197 | PUTRGBA(dst_2,py_2,pa_2,0,1,24); | |
198 | ||
199 | LOADCHROMA(1); | |
200 | PUTRGBA(dst_2,py_2,pa_1,1,1,24); | |
201 | PUTRGBA(dst_1,py_1,pa_2,1,0,24); | |
3acd545f CS |
202 | |
203 | LOADCHROMA(2); | |
204 | PUTRGBA(dst_1,py_1,pa_1,2,0,24); | |
205 | PUTRGBA(dst_2,py_2,pa_2,2,1,24); | |
206 | ||
207 | LOADCHROMA(3); | |
208 | PUTRGBA(dst_2,py_2,pa_1,3,1,24); | |
209 | PUTRGBA(dst_1,py_1,pa_2,3,0,24); | |
210 | pa_1 += 8;\ | |
211 | pa_2 += 8;\ | |
212 | ENDYUV2RGBLINE(8) | |
213 | LOADCHROMA(0); | |
214 | PUTRGBA(dst_1,py_1,pa_1,0,0,24); | |
215 | PUTRGBA(dst_2,py_2,pa_2,0,1,24); | |
216 | ||
217 | LOADCHROMA(1); | |
218 | PUTRGBA(dst_2,py_2,pa_1,1,1,24); | |
219 | PUTRGBA(dst_1,py_1,pa_2,1,0,24); | |
220 | ENDYUV2RGBFUNC() | |
221 | ||
222 | YUV2RGBFUNC(yuva2argb_c, uint32_t, 1) | |
223 | LOADCHROMA(0); | |
224 | PUTRGBA(dst_1,py_1,pa_1,0,0,0); | |
225 | PUTRGBA(dst_2,py_2,pa_2,0,1,0); | |
226 | ||
227 | LOADCHROMA(1); | |
228 | PUTRGBA(dst_2,py_2,pa_2,1,1,0); | |
229 | PUTRGBA(dst_1,py_1,pa_1,1,0,0); | |
3acd545f CS |
230 | |
231 | LOADCHROMA(2); | |
232 | PUTRGBA(dst_1,py_1,pa_1,2,0,0); | |
233 | PUTRGBA(dst_2,py_2,pa_2,2,1,0); | |
234 | ||
235 | LOADCHROMA(3); | |
236 | PUTRGBA(dst_2,py_2,pa_2,3,1,0); | |
237 | PUTRGBA(dst_1,py_1,pa_1,3,0,0); | |
238 | pa_1 += 8;\ | |
239 | pa_2 += 8;\ | |
240 | ENDYUV2RGBLINE(8) | |
241 | LOADCHROMA(0); | |
242 | PUTRGBA(dst_1,py_1,pa_1,0,0,0); | |
243 | PUTRGBA(dst_2,py_2,pa_2,0,1,0); | |
244 | ||
245 | LOADCHROMA(1); | |
246 | PUTRGBA(dst_2,py_2,pa_2,1,1,0); | |
247 | PUTRGBA(dst_1,py_1,pa_1,1,0,0); | |
248 | ENDYUV2RGBFUNC() | |
249 | ||
9a10a076 | 250 | YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0) |
e76709d8 KS |
251 | LOADCHROMA(0); |
252 | PUTRGB24(dst_1,py_1,0); | |
253 | PUTRGB24(dst_2,py_2,0); | |
254 | ||
255 | LOADCHROMA(1); | |
256 | PUTRGB24(dst_2,py_2,1); | |
257 | PUTRGB24(dst_1,py_1,1); | |
258 | ||
259 | LOADCHROMA(2); | |
260 | PUTRGB24(dst_1,py_1,2); | |
261 | PUTRGB24(dst_2,py_2,2); | |
262 | ||
263 | LOADCHROMA(3); | |
264 | PUTRGB24(dst_2,py_2,3); | |
265 | PUTRGB24(dst_1,py_1,3); | |
266 | ENDYUV2RGBLINE(24) | |
267 | LOADCHROMA(0); | |
268 | PUTRGB24(dst_1,py_1,0); | |
269 | PUTRGB24(dst_2,py_2,0); | |
270 | ||
271 | LOADCHROMA(1); | |
272 | PUTRGB24(dst_2,py_2,1); | |
273 | PUTRGB24(dst_1,py_1,1); | |
274 | ENDYUV2RGBFUNC() | |
275 | ||
276 | // only trivial mods from yuv2rgb_c_24_rgb | |
9a10a076 | 277 | YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0) |
e76709d8 KS |
278 | LOADCHROMA(0); |
279 | PUTBGR24(dst_1,py_1,0); | |
280 | PUTBGR24(dst_2,py_2,0); | |
281 | ||
282 | LOADCHROMA(1); | |
283 | PUTBGR24(dst_2,py_2,1); | |
284 | PUTBGR24(dst_1,py_1,1); | |
285 | ||
286 | LOADCHROMA(2); | |
287 | PUTBGR24(dst_1,py_1,2); | |
288 | PUTBGR24(dst_2,py_2,2); | |
289 | ||
290 | LOADCHROMA(3); | |
291 | PUTBGR24(dst_2,py_2,3); | |
292 | PUTBGR24(dst_1,py_1,3); | |
293 | ENDYUV2RGBLINE(24) | |
294 | LOADCHROMA(0); | |
295 | PUTBGR24(dst_1,py_1,0); | |
296 | PUTBGR24(dst_2,py_2,0); | |
297 | ||
298 | LOADCHROMA(1); | |
299 | PUTBGR24(dst_2,py_2,1); | |
300 | PUTBGR24(dst_1,py_1,1); | |
301 | ENDYUV2RGBFUNC() | |
302 | ||
303 | // This is exactly the same code as yuv2rgb_c_32 except for the types of | |
304 | // r, g, b, dst_1, dst_2 | |
9a10a076 | 305 | YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0) |
e76709d8 KS |
306 | LOADCHROMA(0); |
307 | PUTRGB(dst_1,py_1,0,0); | |
308 | PUTRGB(dst_2,py_2,0,1); | |
309 | ||
310 | LOADCHROMA(1); | |
311 | PUTRGB(dst_2,py_2,1,1); | |
312 | PUTRGB(dst_1,py_1,1,0); | |
313 | ||
314 | LOADCHROMA(2); | |
315 | PUTRGB(dst_1,py_1,2,0); | |
316 | PUTRGB(dst_2,py_2,2,1); | |
317 | ||
318 | LOADCHROMA(3); | |
319 | PUTRGB(dst_2,py_2,3,1); | |
320 | PUTRGB(dst_1,py_1,3,0); | |
321 | CLOSEYUV2RGBFUNC(8) | |
322 | ||
323 | // This is exactly the same code as yuv2rgb_c_32 except for the types of | |
324 | // r, g, b, dst_1, dst_2 | |
9a10a076 | 325 | YUV2RGBFUNC(yuv2rgb_c_8, uint8_t, 0) |
e76709d8 KS |
326 | LOADCHROMA(0); |
327 | PUTRGB(dst_1,py_1,0,0); | |
328 | PUTRGB(dst_2,py_2,0,1); | |
329 | ||
330 | LOADCHROMA(1); | |
331 | PUTRGB(dst_2,py_2,1,1); | |
332 | PUTRGB(dst_1,py_1,1,0); | |
333 | ||
334 | LOADCHROMA(2); | |
335 | PUTRGB(dst_1,py_1,2,0); | |
336 | PUTRGB(dst_2,py_2,2,1); | |
337 | ||
338 | LOADCHROMA(3); | |
339 | PUTRGB(dst_2,py_2,3,1); | |
340 | PUTRGB(dst_1,py_1,3,0); | |
341 | CLOSEYUV2RGBFUNC(8) | |
342 | ||
343 | // r, g, b, dst_1, dst_2 | |
9a10a076 | 344 | YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0) |
e76709d8 KS |
345 | const uint8_t *d32 = dither_8x8_32[y&7]; |
346 | const uint8_t *d64 = dither_8x8_73[y&7]; | |
347 | #define PUTRGB8(dst,src,i,o) \ | |
348 | Y = src[2*i]; \ | |
349 | dst[2*i] = r[Y+d32[0+o]] + g[Y+d32[0+o]] + b[Y+d64[0+o]]; \ | |
350 | Y = src[2*i+1]; \ | |
351 | dst[2*i+1] = r[Y+d32[1+o]] + g[Y+d32[1+o]] + b[Y+d64[1+o]]; | |
352 | ||
353 | LOADCHROMA(0); | |
354 | PUTRGB8(dst_1,py_1,0,0); | |
355 | PUTRGB8(dst_2,py_2,0,0+8); | |
356 | ||
357 | LOADCHROMA(1); | |
358 | PUTRGB8(dst_2,py_2,1,2+8); | |
359 | PUTRGB8(dst_1,py_1,1,2); | |
360 | ||
361 | LOADCHROMA(2); | |
362 | PUTRGB8(dst_1,py_1,2,4); | |
363 | PUTRGB8(dst_2,py_2,2,4+8); | |
364 | ||
365 | LOADCHROMA(3); | |
366 | PUTRGB8(dst_2,py_2,3,6+8); | |
367 | PUTRGB8(dst_1,py_1,3,6); | |
368 | CLOSEYUV2RGBFUNC(8) | |
369 | ||
370 | ||
371 | // This is exactly the same code as yuv2rgb_c_32 except for the types of | |
372 | // r, g, b, dst_1, dst_2 | |
9a10a076 | 373 | YUV2RGBFUNC(yuv2rgb_c_4, uint8_t, 0) |
e76709d8 KS |
374 | int acc; |
375 | #define PUTRGB4(dst,src,i) \ | |
376 | Y = src[2*i]; \ | |
377 | acc = r[Y] + g[Y] + b[Y]; \ | |
378 | Y = src[2*i+1]; \ | |
379 | acc |= (r[Y] + g[Y] + b[Y])<<4; \ | |
380 | dst[i] = acc; | |
381 | ||
382 | LOADCHROMA(0); | |
383 | PUTRGB4(dst_1,py_1,0); | |
384 | PUTRGB4(dst_2,py_2,0); | |
385 | ||
386 | LOADCHROMA(1); | |
387 | PUTRGB4(dst_2,py_2,1); | |
388 | PUTRGB4(dst_1,py_1,1); | |
389 | ||
390 | LOADCHROMA(2); | |
391 | PUTRGB4(dst_1,py_1,2); | |
392 | PUTRGB4(dst_2,py_2,2); | |
393 | ||
394 | LOADCHROMA(3); | |
395 | PUTRGB4(dst_2,py_2,3); | |
396 | PUTRGB4(dst_1,py_1,3); | |
397 | CLOSEYUV2RGBFUNC(4) | |
398 | ||
9a10a076 | 399 | YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0) |
e76709d8 KS |
400 | const uint8_t *d64 = dither_8x8_73[y&7]; |
401 | const uint8_t *d128 = dither_8x8_220[y&7]; | |
402 | int acc; | |
403 | ||
404 | #define PUTRGB4D(dst,src,i,o) \ | |
405 | Y = src[2*i]; \ | |
406 | acc = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \ | |
407 | Y = src[2*i+1]; \ | |
408 | acc |= (r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]])<<4; \ | |
409 | dst[i]= acc; | |
410 | ||
411 | LOADCHROMA(0); | |
412 | PUTRGB4D(dst_1,py_1,0,0); | |
413 | PUTRGB4D(dst_2,py_2,0,0+8); | |
414 | ||
415 | LOADCHROMA(1); | |
416 | PUTRGB4D(dst_2,py_2,1,2+8); | |
417 | PUTRGB4D(dst_1,py_1,1,2); | |
418 | ||
419 | LOADCHROMA(2); | |
420 | PUTRGB4D(dst_1,py_1,2,4); | |
421 | PUTRGB4D(dst_2,py_2,2,4+8); | |
422 | ||
423 | LOADCHROMA(3); | |
424 | PUTRGB4D(dst_2,py_2,3,6+8); | |
425 | PUTRGB4D(dst_1,py_1,3,6); | |
426 | CLOSEYUV2RGBFUNC(4) | |
427 | ||
428 | // This is exactly the same code as yuv2rgb_c_32 except for the types of | |
429 | // r, g, b, dst_1, dst_2 | |
9a10a076 | 430 | YUV2RGBFUNC(yuv2rgb_c_4b, uint8_t, 0) |
e76709d8 KS |
431 | LOADCHROMA(0); |
432 | PUTRGB(dst_1,py_1,0,0); | |
433 | PUTRGB(dst_2,py_2,0,1); | |
434 | ||
435 | LOADCHROMA(1); | |
436 | PUTRGB(dst_2,py_2,1,1); | |
437 | PUTRGB(dst_1,py_1,1,0); | |
438 | ||
439 | LOADCHROMA(2); | |
440 | PUTRGB(dst_1,py_1,2,0); | |
441 | PUTRGB(dst_2,py_2,2,1); | |
442 | ||
443 | LOADCHROMA(3); | |
444 | PUTRGB(dst_2,py_2,3,1); | |
445 | PUTRGB(dst_1,py_1,3,0); | |
446 | CLOSEYUV2RGBFUNC(8) | |
447 | ||
9a10a076 | 448 | YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0) |
e76709d8 KS |
449 | const uint8_t *d64 = dither_8x8_73[y&7]; |
450 | const uint8_t *d128 = dither_8x8_220[y&7]; | |
451 | ||
452 | #define PUTRGB4DB(dst,src,i,o) \ | |
453 | Y = src[2*i]; \ | |
454 | dst[2*i] = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \ | |
455 | Y = src[2*i+1]; \ | |
456 | dst[2*i+1] = r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]]; | |
457 | ||
458 | LOADCHROMA(0); | |
459 | PUTRGB4DB(dst_1,py_1,0,0); | |
460 | PUTRGB4DB(dst_2,py_2,0,0+8); | |
461 | ||
462 | LOADCHROMA(1); | |
463 | PUTRGB4DB(dst_2,py_2,1,2+8); | |
464 | PUTRGB4DB(dst_1,py_1,1,2); | |
465 | ||
466 | LOADCHROMA(2); | |
467 | PUTRGB4DB(dst_1,py_1,2,4); | |
468 | PUTRGB4DB(dst_2,py_2,2,4+8); | |
469 | ||
470 | LOADCHROMA(3); | |
471 | PUTRGB4DB(dst_2,py_2,3,6+8); | |
472 | PUTRGB4DB(dst_1,py_1,3,6); | |
473 | CLOSEYUV2RGBFUNC(8) | |
474 | ||
9a10a076 | 475 | YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0) |
e76709d8 KS |
476 | const uint8_t *d128 = dither_8x8_220[y&7]; |
477 | char out_1 = 0, out_2 = 0; | |
478 | g= c->table_gU[128] + c->table_gV[128]; | |
479 | ||
480 | #define PUTRGB1(out,src,i,o) \ | |
481 | Y = src[2*i]; \ | |
482 | out+= out + g[Y+d128[0+o]]; \ | |
483 | Y = src[2*i+1]; \ | |
484 | out+= out + g[Y+d128[1+o]]; | |
485 | ||
486 | PUTRGB1(out_1,py_1,0,0); | |
487 | PUTRGB1(out_2,py_2,0,0+8); | |
488 | ||
489 | PUTRGB1(out_2,py_2,1,2+8); | |
490 | PUTRGB1(out_1,py_1,1,2); | |
491 | ||
492 | PUTRGB1(out_1,py_1,2,4); | |
493 | PUTRGB1(out_2,py_2,2,4+8); | |
494 | ||
495 | PUTRGB1(out_2,py_2,3,6+8); | |
496 | PUTRGB1(out_1,py_1,3,6); | |
497 | ||
498 | dst_1[0]= out_1; | |
499 | dst_2[0]= out_2; | |
500 | CLOSEYUV2RGBFUNC(1) | |
501 | ||
780daf2b | 502 | SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) |
e76709d8 KS |
503 | { |
504 | SwsFunc t = NULL; | |
505 | #if (HAVE_MMX2 || HAVE_MMX) && CONFIG_GPL | |
befa8e66 | 506 | t = ff_yuv2rgb_init_mmx(c); |
e76709d8 KS |
507 | #endif |
508 | #if HAVE_VIS | |
780daf2b | 509 | t = ff_yuv2rgb_init_vis(c); |
e76709d8 KS |
510 | #endif |
511 | #if CONFIG_MLIB | |
780daf2b | 512 | t = ff_yuv2rgb_init_mlib(c); |
e76709d8 | 513 | #endif |
29ce0433 | 514 | #if HAVE_ALTIVEC |
e76709d8 | 515 | if (c->flags & SWS_CPU_CAPS_ALTIVEC) |
780daf2b | 516 | t = ff_yuv2rgb_init_altivec(c); |
e76709d8 KS |
517 | #endif |
518 | ||
519 | #if ARCH_BFIN | |
520 | if (c->flags & SWS_CPU_CAPS_BFIN) | |
780daf2b | 521 | t = ff_yuv2rgb_get_func_ptr_bfin(c); |
e76709d8 KS |
522 | #endif |
523 | ||
524 | if (t) | |
525 | return t; | |
526 | ||
527 | av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found.\n"); | |
528 | ||
529 | switch (c->dstFormat) { | |
68e7f482 KS |
530 | case PIX_FMT_RGB48BE: |
531 | case PIX_FMT_RGB48LE: return yuv2rgb_c_48; | |
3acd545f CS |
532 | case PIX_FMT_ARGB: |
533 | case PIX_FMT_ABGR: if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c; | |
534 | case PIX_FMT_RGBA: | |
535 | case PIX_FMT_BGRA: return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32; | |
e76709d8 KS |
536 | case PIX_FMT_RGB24: return yuv2rgb_c_24_rgb; |
537 | case PIX_FMT_BGR24: return yuv2rgb_c_24_bgr; | |
538 | case PIX_FMT_RGB565: | |
539 | case PIX_FMT_BGR565: | |
540 | case PIX_FMT_RGB555: | |
541 | case PIX_FMT_BGR555: return yuv2rgb_c_16; | |
542 | case PIX_FMT_RGB8: | |
543 | case PIX_FMT_BGR8: return yuv2rgb_c_8_ordered_dither; | |
544 | case PIX_FMT_RGB4: | |
545 | case PIX_FMT_BGR4: return yuv2rgb_c_4_ordered_dither; | |
546 | case PIX_FMT_RGB4_BYTE: | |
547 | case PIX_FMT_BGR4_BYTE: return yuv2rgb_c_4b_ordered_dither; | |
548 | case PIX_FMT_MONOBLACK: return yuv2rgb_c_1_ordered_dither; | |
549 | default: | |
550 | assert(0); | |
551 | } | |
552 | return NULL; | |
553 | } | |
554 | ||
555 | static void fill_table(uint8_t* table[256], const int elemsize, const int inc, uint8_t *y_table) | |
556 | { | |
557 | int i; | |
558 | int64_t cb = 0; | |
559 | ||
560 | y_table -= elemsize * (inc >> 9); | |
561 | ||
562 | for (i = 0; i < 256; i++) { | |
563 | table[i] = y_table + elemsize * (cb >> 16); | |
564 | cb += inc; | |
565 | } | |
566 | } | |
567 | ||
568 | static void fill_gv_table(int table[256], const int elemsize, const int inc) | |
569 | { | |
570 | int i; | |
571 | int64_t cb = 0; | |
572 | int off = -(inc >> 9); | |
573 | ||
574 | for (i = 0; i < 256; i++) { | |
575 | table[i] = elemsize * (off + (cb >> 16)); | |
576 | cb += inc; | |
577 | } | |
578 | } | |
579 | ||
780daf2b DB |
580 | av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange, |
581 | int brightness, int contrast, int saturation) | |
e76709d8 KS |
582 | { |
583 | const int isRgb = c->dstFormat==PIX_FMT_RGB32 | |
584 | || c->dstFormat==PIX_FMT_RGB32_1 | |
585 | || c->dstFormat==PIX_FMT_BGR24 | |
586 | || c->dstFormat==PIX_FMT_RGB565 | |
587 | || c->dstFormat==PIX_FMT_RGB555 | |
588 | || c->dstFormat==PIX_FMT_RGB8 | |
589 | || c->dstFormat==PIX_FMT_RGB4 | |
590 | || c->dstFormat==PIX_FMT_RGB4_BYTE | |
591 | || c->dstFormat==PIX_FMT_MONOBLACK; | |
592 | const int bpp = fmt_depth(c->dstFormat); | |
593 | uint8_t *y_table; | |
594 | uint16_t *y_table16; | |
595 | uint32_t *y_table32; | |
3acd545f | 596 | int i, base, rbase, gbase, bbase, abase, needAlpha; |
e76709d8 KS |
597 | const int yoffs = fullRange ? 384 : 326; |
598 | ||
599 | int64_t crv = inv_table[0]; | |
600 | int64_t cbu = inv_table[1]; | |
601 | int64_t cgu = -inv_table[2]; | |
602 | int64_t cgv = -inv_table[3]; | |
603 | int64_t cy = 1<<16; | |
604 | int64_t oy = 0; | |
605 | ||
606 | int64_t yb = 0; | |
607 | ||
608 | if (!fullRange) { | |
609 | cy = (cy*255) / 219; | |
610 | oy = 16<<16; | |
611 | } else { | |
612 | crv = (crv*224) / 255; | |
613 | cbu = (cbu*224) / 255; | |
614 | cgu = (cgu*224) / 255; | |
615 | cgv = (cgv*224) / 255; | |
616 | } | |
617 | ||
618 | cy = (cy *contrast ) >> 16; | |
619 | crv = (crv*contrast * saturation) >> 32; | |
620 | cbu = (cbu*contrast * saturation) >> 32; | |
621 | cgu = (cgu*contrast * saturation) >> 32; | |
622 | cgv = (cgv*contrast * saturation) >> 32; | |
623 | oy -= 256*brightness; | |
624 | ||
625 | //scale coefficients by cy | |
626 | crv = ((crv << 16) + 0x8000) / cy; | |
627 | cbu = ((cbu << 16) + 0x8000) / cy; | |
628 | cgu = ((cgu << 16) + 0x8000) / cy; | |
629 | cgv = ((cgv << 16) + 0x8000) / cy; | |
630 | ||
631 | av_free(c->yuvTable); | |
632 | ||
633 | switch (bpp) { | |
634 | case 1: | |
635 | c->yuvTable = av_malloc(1024); | |
636 | y_table = c->yuvTable; | |
637 | yb = -(384<<16) - oy; | |
638 | for (i = 0; i < 1024-110; i++) { | |
639 | y_table[i+110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7; | |
640 | yb += cy; | |
641 | } | |
642 | fill_table(c->table_gU, 1, cgu, y_table + yoffs); | |
643 | fill_gv_table(c->table_gV, 1, cgv); | |
644 | break; | |
645 | case 4: | |
646 | case 4|128: | |
647 | rbase = isRgb ? 3 : 0; | |
648 | gbase = 1; | |
649 | bbase = isRgb ? 0 : 3; | |
650 | c->yuvTable = av_malloc(1024*3); | |
651 | y_table = c->yuvTable; | |
652 | yb = -(384<<16) - oy; | |
653 | for (i = 0; i < 1024-110; i++) { | |
654 | int yval = av_clip_uint8((yb + 0x8000) >> 16); | |
655 | y_table[i+110 ] = (yval >> 7) << rbase; | |
656 | y_table[i+ 37+1024] = ((yval + 43) / 85) << gbase; | |
657 | y_table[i+110+2048] = (yval >> 7) << bbase; | |
658 | yb += cy; | |
659 | } | |
660 | fill_table(c->table_rV, 1, crv, y_table + yoffs); | |
661 | fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024); | |
662 | fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); | |
663 | fill_gv_table(c->table_gV, 1, cgv); | |
664 | break; | |
665 | case 8: | |
666 | rbase = isRgb ? 5 : 0; | |
667 | gbase = isRgb ? 2 : 3; | |
668 | bbase = isRgb ? 0 : 6; | |
669 | c->yuvTable = av_malloc(1024*3); | |
670 | y_table = c->yuvTable; | |
671 | yb = -(384<<16) - oy; | |
672 | for (i = 0; i < 1024-38; i++) { | |
673 | int yval = av_clip_uint8((yb + 0x8000) >> 16); | |
674 | y_table[i+16 ] = ((yval + 18) / 36) << rbase; | |
675 | y_table[i+16+1024] = ((yval + 18) / 36) << gbase; | |
676 | y_table[i+37+2048] = ((yval + 43) / 85) << bbase; | |
677 | yb += cy; | |
678 | } | |
679 | fill_table(c->table_rV, 1, crv, y_table + yoffs); | |
680 | fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024); | |
681 | fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); | |
682 | fill_gv_table(c->table_gV, 1, cgv); | |
683 | break; | |
684 | case 15: | |
685 | case 16: | |
686 | rbase = isRgb ? bpp - 5 : 0; | |
687 | gbase = 5; | |
688 | bbase = isRgb ? 0 : (bpp - 5); | |
689 | c->yuvTable = av_malloc(1024*3*2); | |
690 | y_table16 = c->yuvTable; | |
691 | yb = -(384<<16) - oy; | |
692 | for (i = 0; i < 1024; i++) { | |
693 | uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); | |
694 | y_table16[i ] = (yval >> 3) << rbase; | |
695 | y_table16[i+1024] = (yval >> (18 - bpp)) << gbase; | |
696 | y_table16[i+2048] = (yval >> 3) << bbase; | |
697 | yb += cy; | |
698 | } | |
699 | fill_table(c->table_rV, 2, crv, y_table16 + yoffs); | |
700 | fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); | |
701 | fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048); | |
702 | fill_gv_table(c->table_gV, 2, cgv); | |
703 | break; | |
704 | case 24: | |
68e7f482 | 705 | case 48: |
e76709d8 KS |
706 | c->yuvTable = av_malloc(1024); |
707 | y_table = c->yuvTable; | |
708 | yb = -(384<<16) - oy; | |
709 | for (i = 0; i < 1024; i++) { | |
710 | y_table[i] = av_clip_uint8((yb + 0x8000) >> 16); | |
711 | yb += cy; | |
712 | } | |
713 | fill_table(c->table_rV, 1, crv, y_table + yoffs); | |
714 | fill_table(c->table_gU, 1, cgu, y_table + yoffs); | |
715 | fill_table(c->table_bU, 1, cbu, y_table + yoffs); | |
716 | fill_gv_table(c->table_gV, 1, cgv); | |
717 | break; | |
718 | case 32: | |
719 | base = (c->dstFormat == PIX_FMT_RGB32_1 || c->dstFormat == PIX_FMT_BGR32_1) ? 8 : 0; | |
720 | rbase = base + (isRgb ? 16 : 0); | |
721 | gbase = base + 8; | |
722 | bbase = base + (isRgb ? 0 : 16); | |
3acd545f CS |
723 | needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat); |
724 | if (!needAlpha) | |
725 | abase = (base + 24) & 31; | |
e76709d8 KS |
726 | c->yuvTable = av_malloc(1024*3*4); |
727 | y_table32 = c->yuvTable; | |
728 | yb = -(384<<16) - oy; | |
729 | for (i = 0; i < 1024; i++) { | |
730 | uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); | |
3acd545f | 731 | y_table32[i ] = (yval << rbase) + (needAlpha ? 0 : (255 << abase)); |
e76709d8 KS |
732 | y_table32[i+1024] = yval << gbase; |
733 | y_table32[i+2048] = yval << bbase; | |
734 | yb += cy; | |
735 | } | |
736 | fill_table(c->table_rV, 4, crv, y_table32 + yoffs); | |
737 | fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024); | |
738 | fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048); | |
739 | fill_gv_table(c->table_gV, 4, cgv); | |
740 | break; | |
741 | default: | |
742 | c->yuvTable = NULL; | |
743 | av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp); | |
744 | return -1; | |
745 | } | |
746 | return 0; | |
747 | } |