output.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001-2012 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <assert.h>
22 #include <math.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "libavutil/attributes.h"
28 #include "libavutil/avutil.h"
29 #include "libavutil/avassert.h"
30 #include "libavutil/bswap.h"
31 #include "libavutil/cpu.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/pixdesc.h"
35 #include "config.h"
36 #include "rgb2rgb.h"
37 #include "swscale.h"
38 #include "swscale_internal.h"
39 
40 DECLARE_ALIGNED(8, const uint8_t, dither_2x2_4)[][8]={
41 { 1, 3, 1, 3, 1, 3, 1, 3, },
42 { 2, 0, 2, 0, 2, 0, 2, 0, },
43 { 1, 3, 1, 3, 1, 3, 1, 3, },
44 };
45 
46 DECLARE_ALIGNED(8, const uint8_t, dither_2x2_8)[][8]={
47 { 6, 2, 6, 2, 6, 2, 6, 2, },
48 { 0, 4, 0, 4, 0, 4, 0, 4, },
49 { 6, 2, 6, 2, 6, 2, 6, 2, },
50 };
51 
52 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[][8]={
53 { 8, 4, 11, 7, 8, 4, 11, 7, },
54 { 2, 14, 1, 13, 2, 14, 1, 13, },
55 { 10, 6, 9, 5, 10, 6, 9, 5, },
56 { 0, 12, 3, 15, 0, 12, 3, 15, },
57 { 8, 4, 11, 7, 8, 4, 11, 7, },
58 };
59 
60 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[][8]={
61 { 17, 9, 23, 15, 16, 8, 22, 14, },
62 { 5, 29, 3, 27, 4, 28, 2, 26, },
63 { 21, 13, 19, 11, 20, 12, 18, 10, },
64 { 0, 24, 6, 30, 1, 25, 7, 31, },
65 { 16, 8, 22, 14, 17, 9, 23, 15, },
66 { 4, 28, 2, 26, 5, 29, 3, 27, },
67 { 20, 12, 18, 10, 21, 13, 19, 11, },
68 { 1, 25, 7, 31, 0, 24, 6, 30, },
69 { 17, 9, 23, 15, 16, 8, 22, 14, },
70 };
71 
72 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[][8]={
73 { 0, 55, 14, 68, 3, 58, 17, 72, },
74 { 37, 18, 50, 32, 40, 22, 54, 35, },
75 { 9, 64, 5, 59, 13, 67, 8, 63, },
76 { 46, 27, 41, 23, 49, 31, 44, 26, },
77 { 2, 57, 16, 71, 1, 56, 15, 70, },
78 { 39, 21, 52, 34, 38, 19, 51, 33, },
79 { 11, 66, 7, 62, 10, 65, 6, 60, },
80 { 48, 30, 43, 25, 47, 29, 42, 24, },
81 { 0, 55, 14, 68, 3, 58, 17, 72, },
82 };
83 
84 #if 1
85 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
86 {117, 62, 158, 103, 113, 58, 155, 100, },
87 { 34, 199, 21, 186, 31, 196, 17, 182, },
88 {144, 89, 131, 76, 141, 86, 127, 72, },
89 { 0, 165, 41, 206, 10, 175, 52, 217, },
90 {110, 55, 151, 96, 120, 65, 162, 107, },
91 { 28, 193, 14, 179, 38, 203, 24, 189, },
92 {138, 83, 124, 69, 148, 93, 134, 79, },
93 { 7, 172, 48, 213, 3, 168, 45, 210, },
94 {117, 62, 158, 103, 113, 58, 155, 100, },
95 };
96 #elif 1
97 // tries to correct a gamma of 1.5
98 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
99 { 0, 143, 18, 200, 2, 156, 25, 215, },
100 { 78, 28, 125, 64, 89, 36, 138, 74, },
101 { 10, 180, 3, 161, 16, 195, 8, 175, },
102 {109, 51, 93, 38, 121, 60, 105, 47, },
103 { 1, 152, 23, 210, 0, 147, 20, 205, },
104 { 85, 33, 134, 71, 81, 30, 130, 67, },
105 { 14, 190, 6, 171, 12, 185, 5, 166, },
106 {117, 57, 101, 44, 113, 54, 97, 41, },
107 { 0, 143, 18, 200, 2, 156, 25, 215, },
108 };
109 #elif 1
110 // tries to correct a gamma of 2.0
111 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
112 { 0, 124, 8, 193, 0, 140, 12, 213, },
113 { 55, 14, 104, 42, 66, 19, 119, 52, },
114 { 3, 168, 1, 145, 6, 187, 3, 162, },
115 { 86, 31, 70, 21, 99, 39, 82, 28, },
116 { 0, 134, 11, 206, 0, 129, 9, 200, },
117 { 62, 17, 114, 48, 58, 16, 109, 45, },
118 { 5, 181, 2, 157, 4, 175, 1, 151, },
119 { 95, 36, 78, 26, 90, 34, 74, 24, },
120 { 0, 124, 8, 193, 0, 140, 12, 213, },
121 };
122 #else
123 // tries to correct a gamma of 2.5
124 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
125 { 0, 107, 3, 187, 0, 125, 6, 212, },
126 { 39, 7, 86, 28, 49, 11, 102, 36, },
127 { 1, 158, 0, 131, 3, 180, 1, 151, },
128 { 68, 19, 52, 12, 81, 25, 64, 17, },
129 { 0, 119, 5, 203, 0, 113, 4, 195, },
130 { 45, 9, 96, 33, 42, 8, 91, 30, },
131 { 2, 172, 1, 144, 2, 165, 0, 137, },
132 { 77, 23, 60, 15, 72, 21, 56, 14, },
133 { 0, 107, 3, 187, 0, 125, 6, 212, },
134 };
135 #endif
136 
137 #define output_pixel(pos, val, bias, signedness) \
138  if (big_endian) { \
139  AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
140  } else { \
141  AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
142  }
143 
144 static av_always_inline void
145 yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW,
146  int big_endian, int output_bits)
147 {
148  int i;
149  int shift = 3;
150  av_assert0(output_bits == 16);
151 
152  for (i = 0; i < dstW; i++) {
153  int val = src[i] + (1 << (shift - 1));
154  output_pixel(&dest[i], val, 0, uint);
155  }
156 }
157 
158 static av_always_inline void
159 yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
160  const int32_t **src, uint16_t *dest, int dstW,
161  int big_endian, int output_bits)
162 {
163  int i;
164  int shift = 15;
165  av_assert0(output_bits == 16);
166 
167  for (i = 0; i < dstW; i++) {
168  int val = 1 << (shift - 1);
169  int j;
170 
171  /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline
172  * filters (or anything with negative coeffs, the range can be slightly
173  * wider in both directions. To account for this overflow, we subtract
174  * a constant so it always fits in the signed range (assuming a
175  * reasonable filterSize), and re-add that at the end. */
176  val -= 0x40000000;
177  for (j = 0; j < filterSize; j++)
178  val += src[j][i] * (unsigned)filter[j];
179 
180  output_pixel(&dest[i], val, 0x8000, int);
181  }
182 }
183 
184 #undef output_pixel
185 
186 #define output_pixel(pos, val) \
187  if (big_endian) { \
188  AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
189  } else { \
190  AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
191  }
192 
193 static av_always_inline void
194 yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW,
195  int big_endian, int output_bits)
196 {
197  int i;
198  int shift = 15 - output_bits;
199 
200  for (i = 0; i < dstW; i++) {
201  int val = src[i] + (1 << (shift - 1));
202  output_pixel(&dest[i], val);
203  }
204 }
205 
206 static av_always_inline void
207 yuv2planeX_10_c_template(const int16_t *filter, int filterSize,
208  const int16_t **src, uint16_t *dest, int dstW,
209  int big_endian, int output_bits)
210 {
211  int i;
212  int shift = 11 + 16 - output_bits;
213 
214  for (i = 0; i < dstW; i++) {
215  int val = 1 << (shift - 1);
216  int j;
217 
218  for (j = 0; j < filterSize; j++)
219  val += src[j][i] * filter[j];
220 
221  output_pixel(&dest[i], val);
222  }
223 }
224 
225 #undef output_pixel
226 
227 #define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \
228 static void yuv2plane1_ ## bits ## BE_LE ## _c(const int16_t *src, \
229  uint8_t *dest, int dstW, \
230  const uint8_t *dither, int offset)\
231 { \
232  yuv2plane1_ ## template_size ## _c_template((const typeX_t *) src, \
233  (uint16_t *) dest, dstW, is_be, bits); \
234 }\
235 static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filterSize, \
236  const int16_t **src, uint8_t *dest, int dstW, \
237  const uint8_t *dither, int offset)\
238 { \
239  yuv2planeX_## template_size ## _c_template(filter, \
240  filterSize, (const typeX_t **) src, \
241  (uint16_t *) dest, dstW, is_be, bits); \
242 }
243 yuv2NBPS( 9, BE, 1, 10, int16_t)
244 yuv2NBPS( 9, LE, 0, 10, int16_t)
245 yuv2NBPS(10, BE, 1, 10, int16_t)
246 yuv2NBPS(10, LE, 0, 10, int16_t)
247 yuv2NBPS(12, BE, 1, 10, int16_t)
248 yuv2NBPS(12, LE, 0, 10, int16_t)
249 yuv2NBPS(14, BE, 1, 10, int16_t)
250 yuv2NBPS(14, LE, 0, 10, int16_t)
251 yuv2NBPS(16, BE, 1, 16, int32_t)
252 yuv2NBPS(16, LE, 0, 16, int32_t)
253 
254 static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
255  const int16_t **src, uint8_t *dest, int dstW,
256  const uint8_t *dither, int offset)
257 {
258  int i;
259  for (i=0; i<dstW; i++) {
260  int val = dither[(i + offset) & 7] << 12;
261  int j;
262  for (j=0; j<filterSize; j++)
263  val += src[j][i] * filter[j];
264 
265  dest[i]= av_clip_uint8(val>>19);
266  }
267 }
268 
269 static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW,
270  const uint8_t *dither, int offset)
271 {
272  int i;
273  for (i=0; i<dstW; i++) {
274  int val = (src[i] + dither[(i + offset) & 7]) >> 7;
275  dest[i]= av_clip_uint8(val);
276  }
277 }
278 
279 static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
280  const int16_t **chrUSrc, const int16_t **chrVSrc,
281  uint8_t *dest, int chrDstW)
282 {
283  enum AVPixelFormat dstFormat = c->dstFormat;
284  const uint8_t *chrDither = c->chrDither8;
285  int i;
286 
287  if (dstFormat == AV_PIX_FMT_NV12)
288  for (i=0; i<chrDstW; i++) {
289  int u = chrDither[i & 7] << 12;
290  int v = chrDither[(i + 3) & 7] << 12;
291  int j;
292  for (j=0; j<chrFilterSize; j++) {
293  u += chrUSrc[j][i] * chrFilter[j];
294  v += chrVSrc[j][i] * chrFilter[j];
295  }
296 
297  dest[2*i]= av_clip_uint8(u>>19);
298  dest[2*i+1]= av_clip_uint8(v>>19);
299  }
300  else
301  for (i=0; i<chrDstW; i++) {
302  int u = chrDither[i & 7] << 12;
303  int v = chrDither[(i + 3) & 7] << 12;
304  int j;
305  for (j=0; j<chrFilterSize; j++) {
306  u += chrUSrc[j][i] * chrFilter[j];
307  v += chrVSrc[j][i] * chrFilter[j];
308  }
309 
310  dest[2*i]= av_clip_uint8(v>>19);
311  dest[2*i+1]= av_clip_uint8(u>>19);
312  }
313 }
314 
315 #define accumulate_bit(acc, val) \
316  acc <<= 1; \
317  acc |= (val) >= (128 + 110)
318 #define output_pixel(pos, acc) \
319  if (target == AV_PIX_FMT_MONOBLACK) { \
320  pos = acc; \
321  } else { \
322  pos = ~acc; \
323  }
324 
325 static av_always_inline void
326 yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
327  const int16_t **lumSrc, int lumFilterSize,
328  const int16_t *chrFilter, const int16_t **chrUSrc,
329  const int16_t **chrVSrc, int chrFilterSize,
330  const int16_t **alpSrc, uint8_t *dest, int dstW,
331  int y, enum AVPixelFormat target)
332 {
333  const uint8_t * const d128=dither_8x8_220[y&7];
334  int i;
335  unsigned acc = 0;
336  int err = 0;
337 
338  for (i = 0; i < dstW; i += 2) {
339  int j;
340  int Y1 = 1 << 18;
341  int Y2 = 1 << 18;
342 
343  for (j = 0; j < lumFilterSize; j++) {
344  Y1 += lumSrc[j][i] * lumFilter[j];
345  Y2 += lumSrc[j][i+1] * lumFilter[j];
346  }
347  Y1 >>= 19;
348  Y2 >>= 19;
349  if ((Y1 | Y2) & 0x100) {
350  Y1 = av_clip_uint8(Y1);
351  Y2 = av_clip_uint8(Y2);
352  }
353  if (c->flags & SWS_ERROR_DIFFUSION) {
354  Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
355  c->dither_error[0][i] = err;
356  acc = 2*acc + (Y1 >= 128);
357  Y1 -= 220*(acc&1);
358 
359  err = Y2 + ((7*Y1 + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4);
360  c->dither_error[0][i+1] = Y1;
361  acc = 2*acc + (err >= 128);
362  err -= 220*(acc&1);
363  } else {
364  accumulate_bit(acc, Y1 + d128[(i + 0) & 7]);
365  accumulate_bit(acc, Y2 + d128[(i + 1) & 7]);
366  }
367  if ((i & 7) == 6) {
368  output_pixel(*dest++, acc);
369  }
370  }
371  c->dither_error[0][i] = err;
372 
373  if (i & 6) {
374  output_pixel(*dest, acc);
375  }
376 }
377 
378 static av_always_inline void
379 yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
380  const int16_t *ubuf[2], const int16_t *vbuf[2],
381  const int16_t *abuf[2], uint8_t *dest, int dstW,
382  int yalpha, int uvalpha, int y,
383  enum AVPixelFormat target)
384 {
385  const int16_t *buf0 = buf[0], *buf1 = buf[1];
386  const uint8_t * const d128 = dither_8x8_220[y & 7];
387  int yalpha1 = 4096 - yalpha;
388  int i;
389 
390  if (c->flags & SWS_ERROR_DIFFUSION) {
391  int err = 0;
392  int acc = 0;
393  for (i = 0; i < dstW; i +=2) {
394  int Y;
395 
396  Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
397  Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
398  c->dither_error[0][i] = err;
399  acc = 2*acc + (Y >= 128);
400  Y -= 220*(acc&1);
401 
402  err = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
403  err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
404  c->dither_error[0][i+1] = Y;
405  acc = 2*acc + (err >= 128);
406  err -= 220*(acc&1);
407 
408  if ((i & 7) == 6)
409  output_pixel(*dest++, acc);
410  }
411  c->dither_error[0][i] = err;
412  } else {
413  for (i = 0; i < dstW; i += 8) {
414  int Y, acc = 0;
415 
416  Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
417  accumulate_bit(acc, Y + d128[0]);
418  Y = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
419  accumulate_bit(acc, Y + d128[1]);
420  Y = (buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19;
421  accumulate_bit(acc, Y + d128[2]);
422  Y = (buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19;
423  accumulate_bit(acc, Y + d128[3]);
424  Y = (buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19;
425  accumulate_bit(acc, Y + d128[4]);
426  Y = (buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19;
427  accumulate_bit(acc, Y + d128[5]);
428  Y = (buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19;
429  accumulate_bit(acc, Y + d128[6]);
430  Y = (buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19;
431  accumulate_bit(acc, Y + d128[7]);
432 
433  output_pixel(*dest++, acc);
434  }
435  }
436 }
437 
438 static av_always_inline void
439 yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
440  const int16_t *ubuf[2], const int16_t *vbuf[2],
441  const int16_t *abuf0, uint8_t *dest, int dstW,
442  int uvalpha, int y, enum AVPixelFormat target)
443 {
444  const uint8_t * const d128 = dither_8x8_220[y & 7];
445  int i;
446 
447  if (c->flags & SWS_ERROR_DIFFUSION) {
448  int err = 0;
449  int acc = 0;
450  for (i = 0; i < dstW; i +=2) {
451  int Y;
452 
453  Y = ((buf0[i + 0] + 64) >> 7);
454  Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
455  c->dither_error[0][i] = err;
456  acc = 2*acc + (Y >= 128);
457  Y -= 220*(acc&1);
458 
459  err = ((buf0[i + 1] + 64) >> 7);
460  err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
461  c->dither_error[0][i+1] = Y;
462  acc = 2*acc + (err >= 128);
463  err -= 220*(acc&1);
464 
465  if ((i & 7) == 6)
466  output_pixel(*dest++, acc);
467  }
468  c->dither_error[0][i] = err;
469  } else {
470  for (i = 0; i < dstW; i += 8) {
471  int acc = 0;
472  accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]);
473  accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]);
474  accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]);
475  accumulate_bit(acc, ((buf0[i + 3] + 64) >> 7) + d128[3]);
476  accumulate_bit(acc, ((buf0[i + 4] + 64) >> 7) + d128[4]);
477  accumulate_bit(acc, ((buf0[i + 5] + 64) >> 7) + d128[5]);
478  accumulate_bit(acc, ((buf0[i + 6] + 64) >> 7) + d128[6]);
479  accumulate_bit(acc, ((buf0[i + 7] + 64) >> 7) + d128[7]);
480 
481  output_pixel(*dest++, acc);
482  }
483  }
484 }
485 
486 #undef output_pixel
487 #undef accumulate_bit
488 
489 #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
490 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
491  const int16_t **lumSrc, int lumFilterSize, \
492  const int16_t *chrFilter, const int16_t **chrUSrc, \
493  const int16_t **chrVSrc, int chrFilterSize, \
494  const int16_t **alpSrc, uint8_t *dest, int dstW, \
495  int y) \
496 { \
497  name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
498  chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
499  alpSrc, dest, dstW, y, fmt); \
500 } \
501  \
502 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
503  const int16_t *ubuf[2], const int16_t *vbuf[2], \
504  const int16_t *abuf[2], uint8_t *dest, int dstW, \
505  int yalpha, int uvalpha, int y) \
506 { \
507  name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
508  dest, dstW, yalpha, uvalpha, y, fmt); \
509 } \
510  \
511 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
512  const int16_t *ubuf[2], const int16_t *vbuf[2], \
513  const int16_t *abuf0, uint8_t *dest, int dstW, \
514  int uvalpha, int y) \
515 { \
516  name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \
517  abuf0, dest, dstW, uvalpha, \
518  y, fmt); \
519 }
520 
521 YUV2PACKEDWRAPPER(yuv2mono,, white, AV_PIX_FMT_MONOWHITE)
522 YUV2PACKEDWRAPPER(yuv2mono,, black, AV_PIX_FMT_MONOBLACK)
523 
524 #define output_pixels(pos, Y1, U, Y2, V) \
525  if (target == AV_PIX_FMT_YUYV422) { \
526  dest[pos + 0] = Y1; \
527  dest[pos + 1] = U; \
528  dest[pos + 2] = Y2; \
529  dest[pos + 3] = V; \
530  } else { \
531  dest[pos + 0] = U; \
532  dest[pos + 1] = Y1; \
533  dest[pos + 2] = V; \
534  dest[pos + 3] = Y2; \
535  }
536 
537 static av_always_inline void
538 yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
539  const int16_t **lumSrc, int lumFilterSize,
540  const int16_t *chrFilter, const int16_t **chrUSrc,
541  const int16_t **chrVSrc, int chrFilterSize,
542  const int16_t **alpSrc, uint8_t *dest, int dstW,
543  int y, enum AVPixelFormat target)
544 {
545  int i;
546 
547  for (i = 0; i < ((dstW + 1) >> 1); i++) {
548  int j;
549  int Y1 = 1 << 18;
550  int Y2 = 1 << 18;
551  int U = 1 << 18;
552  int V = 1 << 18;
553 
554  for (j = 0; j < lumFilterSize; j++) {
555  Y1 += lumSrc[j][i * 2] * lumFilter[j];
556  Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
557  }
558  for (j = 0; j < chrFilterSize; j++) {
559  U += chrUSrc[j][i] * chrFilter[j];
560  V += chrVSrc[j][i] * chrFilter[j];
561  }
562  Y1 >>= 19;
563  Y2 >>= 19;
564  U >>= 19;
565  V >>= 19;
566  if ((Y1 | Y2 | U | V) & 0x100) {
567  Y1 = av_clip_uint8(Y1);
568  Y2 = av_clip_uint8(Y2);
569  U = av_clip_uint8(U);
570  V = av_clip_uint8(V);
571  }
572  output_pixels(4*i, Y1, U, Y2, V);
573  }
574 }
575 
576 static av_always_inline void
577 yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
578  const int16_t *ubuf[2], const int16_t *vbuf[2],
579  const int16_t *abuf[2], uint8_t *dest, int dstW,
580  int yalpha, int uvalpha, int y,
581  enum AVPixelFormat target)
582 {
583  const int16_t *buf0 = buf[0], *buf1 = buf[1],
584  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
585  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
586  int yalpha1 = 4096 - yalpha;
587  int uvalpha1 = 4096 - uvalpha;
588  int i;
589 
590  for (i = 0; i < ((dstW + 1) >> 1); i++) {
591  int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
592  int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
593  int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
594  int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
595 
596  if ((Y1 | Y2 | U | V) & 0x100) {
597  Y1 = av_clip_uint8(Y1);
598  Y2 = av_clip_uint8(Y2);
599  U = av_clip_uint8(U);
600  V = av_clip_uint8(V);
601  }
602 
603  output_pixels(i * 4, Y1, U, Y2, V);
604  }
605 }
606 
607 static av_always_inline void
608 yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
609  const int16_t *ubuf[2], const int16_t *vbuf[2],
610  const int16_t *abuf0, uint8_t *dest, int dstW,
611  int uvalpha, int y, enum AVPixelFormat target)
612 {
613  const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
614  int i;
615 
616  if (uvalpha < 2048) {
617  for (i = 0; i < ((dstW + 1) >> 1); i++) {
618  int Y1 = (buf0[i * 2 ]+64) >> 7;
619  int Y2 = (buf0[i * 2 + 1]+64) >> 7;
620  int U = (ubuf0[i] +64) >> 7;
621  int V = (vbuf0[i] +64) >> 7;
622 
623  if ((Y1 | Y2 | U | V) & 0x100) {
624  Y1 = av_clip_uint8(Y1);
625  Y2 = av_clip_uint8(Y2);
626  U = av_clip_uint8(U);
627  V = av_clip_uint8(V);
628  }
629 
630  Y1 = av_clip_uint8(Y1);
631  Y2 = av_clip_uint8(Y2);
632  U = av_clip_uint8(U);
633  V = av_clip_uint8(V);
634 
635  output_pixels(i * 4, Y1, U, Y2, V);
636  }
637  } else {
638  const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
639  for (i = 0; i < ((dstW + 1) >> 1); i++) {
640  int Y1 = (buf0[i * 2 ] + 64) >> 7;
641  int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
642  int U = (ubuf0[i] + ubuf1[i]+128) >> 8;
643  int V = (vbuf0[i] + vbuf1[i]+128) >> 8;
644 
645  if ((Y1 | Y2 | U | V) & 0x100) {
646  Y1 = av_clip_uint8(Y1);
647  Y2 = av_clip_uint8(Y2);
648  U = av_clip_uint8(U);
649  V = av_clip_uint8(V);
650  }
651 
652  Y1 = av_clip_uint8(Y1);
653  Y2 = av_clip_uint8(Y2);
654  U = av_clip_uint8(U);
655  V = av_clip_uint8(V);
656 
657  output_pixels(i * 4, Y1, U, Y2, V);
658  }
659  }
660 }
661 
662 #undef output_pixels
663 
664 YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, AV_PIX_FMT_YUYV422)
665 YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, AV_PIX_FMT_UYVY422)
666 
667 #define R_B ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE) ? R : B)
668 #define B_R ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE) ? B : R)
669 #define output_pixel(pos, val) \
670  if (isBE(target)) { \
671  AV_WB16(pos, val); \
672  } else { \
673  AV_WL16(pos, val); \
674  }
675 
676 static av_always_inline void
677 yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
678  const int32_t **lumSrc, int lumFilterSize,
679  const int16_t *chrFilter, const int32_t **chrUSrc,
680  const int32_t **chrVSrc, int chrFilterSize,
681  const int32_t **alpSrc, uint16_t *dest, int dstW,
682  int y, enum AVPixelFormat target)
683 {
684  int i;
685 
686  for (i = 0; i < ((dstW + 1) >> 1); i++) {
687  int j;
688  int Y1 = -0x40000000;
689  int Y2 = -0x40000000;
690  int U = -128 << 23; // 19
691  int V = -128 << 23;
692  int R, G, B;
693 
694  for (j = 0; j < lumFilterSize; j++) {
695  Y1 += lumSrc[j][i * 2] * (unsigned)lumFilter[j];
696  Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
697  }
698  for (j = 0; j < chrFilterSize; j++) {;
699  U += chrUSrc[j][i] * (unsigned)chrFilter[j];
700  V += chrVSrc[j][i] * (unsigned)chrFilter[j];
701  }
702 
703  // 8bit: 12+15=27; 16-bit: 12+19=31
704  Y1 >>= 14; // 10
705  Y1 += 0x10000;
706  Y2 >>= 14;
707  Y2 += 0x10000;
708  U >>= 14;
709  V >>= 14;
710 
711  // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
712  Y1 -= c->yuv2rgb_y_offset;
713  Y2 -= c->yuv2rgb_y_offset;
714  Y1 *= c->yuv2rgb_y_coeff;
715  Y2 *= c->yuv2rgb_y_coeff;
716  Y1 += 1 << 13; // 21
717  Y2 += 1 << 13;
718  // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
719 
720  R = V * c->yuv2rgb_v2r_coeff;
721  G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
722  B = U * c->yuv2rgb_u2b_coeff;
723 
724  // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
725  output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
726  output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
727  output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
728  output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
729  output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
730  output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
731  dest += 6;
732  }
733 }
734 
735 static av_always_inline void
737  const int32_t *ubuf[2], const int32_t *vbuf[2],
738  const int32_t *abuf[2], uint16_t *dest, int dstW,
739  int yalpha, int uvalpha, int y,
740  enum AVPixelFormat target)
741 {
742  const int32_t *buf0 = buf[0], *buf1 = buf[1],
743  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
744  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
745  int yalpha1 = 4096 - yalpha;
746  int uvalpha1 = 4096 - uvalpha;
747  int i;
748 
749  for (i = 0; i < ((dstW + 1) >> 1); i++) {
750  int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 14;
751  int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 14;
752  int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha + (-128 << 23)) >> 14;
753  int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha + (-128 << 23)) >> 14;
754  int R, G, B;
755 
756  Y1 -= c->yuv2rgb_y_offset;
757  Y2 -= c->yuv2rgb_y_offset;
758  Y1 *= c->yuv2rgb_y_coeff;
759  Y2 *= c->yuv2rgb_y_coeff;
760  Y1 += 1 << 13;
761  Y2 += 1 << 13;
762 
763  R = V * c->yuv2rgb_v2r_coeff;
764  G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
765  B = U * c->yuv2rgb_u2b_coeff;
766 
767  output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
768  output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
769  output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
770  output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
771  output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
772  output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
773  dest += 6;
774  }
775 }
776 
777 static av_always_inline void
779  const int32_t *ubuf[2], const int32_t *vbuf[2],
780  const int32_t *abuf0, uint16_t *dest, int dstW,
781  int uvalpha, int y, enum AVPixelFormat target)
782 {
783  const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
784  int i;
785 
786  if (uvalpha < 2048) {
787  for (i = 0; i < ((dstW + 1) >> 1); i++) {
788  int Y1 = (buf0[i * 2] ) >> 2;
789  int Y2 = (buf0[i * 2 + 1]) >> 2;
790  int U = (ubuf0[i] + (-128 << 11)) >> 2;
791  int V = (vbuf0[i] + (-128 << 11)) >> 2;
792  int R, G, B;
793 
794  Y1 -= c->yuv2rgb_y_offset;
795  Y2 -= c->yuv2rgb_y_offset;
796  Y1 *= c->yuv2rgb_y_coeff;
797  Y2 *= c->yuv2rgb_y_coeff;
798  Y1 += 1 << 13;
799  Y2 += 1 << 13;
800 
801  R = V * c->yuv2rgb_v2r_coeff;
802  G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
803  B = U * c->yuv2rgb_u2b_coeff;
804 
805  output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
806  output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
807  output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
808  output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
809  output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
810  output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
811  dest += 6;
812  }
813  } else {
814  const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
815  for (i = 0; i < ((dstW + 1) >> 1); i++) {
816  int Y1 = (buf0[i * 2] ) >> 2;
817  int Y2 = (buf0[i * 2 + 1]) >> 2;
818  int U = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
819  int V = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
820  int R, G, B;
821 
822  Y1 -= c->yuv2rgb_y_offset;
823  Y2 -= c->yuv2rgb_y_offset;
824  Y1 *= c->yuv2rgb_y_coeff;
825  Y2 *= c->yuv2rgb_y_coeff;
826  Y1 += 1 << 13;
827  Y2 += 1 << 13;
828 
829  R = V * c->yuv2rgb_v2r_coeff;
830  G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
831  B = U * c->yuv2rgb_u2b_coeff;
832 
833  output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
834  output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14);
835  output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
836  output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
837  output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14);
838  output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
839  dest += 6;
840  }
841  }
842 }
843 
844 #undef output_pixel
845 #undef r_b
846 #undef b_r
847 
848 #define YUV2PACKED16WRAPPER(name, base, ext, fmt) \
849 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
850  const int16_t **_lumSrc, int lumFilterSize, \
851  const int16_t *chrFilter, const int16_t **_chrUSrc, \
852  const int16_t **_chrVSrc, int chrFilterSize, \
853  const int16_t **_alpSrc, uint8_t *_dest, int dstW, \
854  int y) \
855 { \
856  const int32_t **lumSrc = (const int32_t **) _lumSrc, \
857  **chrUSrc = (const int32_t **) _chrUSrc, \
858  **chrVSrc = (const int32_t **) _chrVSrc, \
859  **alpSrc = (const int32_t **) _alpSrc; \
860  uint16_t *dest = (uint16_t *) _dest; \
861  name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
862  chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
863  alpSrc, dest, dstW, y, fmt); \
864 } \
865  \
866 static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
867  const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
868  const int16_t *_abuf[2], uint8_t *_dest, int dstW, \
869  int yalpha, int uvalpha, int y) \
870 { \
871  const int32_t **buf = (const int32_t **) _buf, \
872  **ubuf = (const int32_t **) _ubuf, \
873  **vbuf = (const int32_t **) _vbuf, \
874  **abuf = (const int32_t **) _abuf; \
875  uint16_t *dest = (uint16_t *) _dest; \
876  name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
877  dest, dstW, yalpha, uvalpha, y, fmt); \
878 } \
879  \
880 static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
881  const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
882  const int16_t *_abuf0, uint8_t *_dest, int dstW, \
883  int uvalpha, int y) \
884 { \
885  const int32_t *buf0 = (const int32_t *) _buf0, \
886  **ubuf = (const int32_t **) _ubuf, \
887  **vbuf = (const int32_t **) _vbuf, \
888  *abuf0 = (const int32_t *) _abuf0; \
889  uint16_t *dest = (uint16_t *) _dest; \
890  name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
891  dstW, uvalpha, y, fmt); \
892 }
893 
894 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, AV_PIX_FMT_RGB48BE)
895 YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE)
896 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE)
897 YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE)
898 
899 /*
900  * Write out 2 RGB pixels in the target pixel format. This function takes a
901  * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of
902  * things like endianness conversion and shifting. The caller takes care of
903  * setting the correct offset in these tables from the chroma (U/V) values.
904  * This function then uses the luminance (Y1/Y2) values to write out the
905  * correct RGB values into the destination buffer.
906  */
907 static av_always_inline void
908 yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
909  unsigned A1, unsigned A2,
910  const void *_r, const void *_g, const void *_b, int y,
911  enum AVPixelFormat target, int hasAlpha)
912 {
913  if (target == AV_PIX_FMT_ARGB || target == AV_PIX_FMT_RGBA ||
914  target == AV_PIX_FMT_ABGR || target == AV_PIX_FMT_BGRA) {
915  uint32_t *dest = (uint32_t *) _dest;
916  const uint32_t *r = (const uint32_t *) _r;
917  const uint32_t *g = (const uint32_t *) _g;
918  const uint32_t *b = (const uint32_t *) _b;
919 
920 #if CONFIG_SMALL
921  int sh = hasAlpha ? ((target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24) : 0;
922 
923  dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
924  dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
925 #else
926  if (hasAlpha) {
927  int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
928 
929  dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
930  dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
931  } else {
932  dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
933  dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
934  }
935 #endif
936  } else if (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) {
937  uint8_t *dest = (uint8_t *) _dest;
938  const uint8_t *r = (const uint8_t *) _r;
939  const uint8_t *g = (const uint8_t *) _g;
940  const uint8_t *b = (const uint8_t *) _b;
941 
942 #define r_b ((target == AV_PIX_FMT_RGB24) ? r : b)
943 #define b_r ((target == AV_PIX_FMT_RGB24) ? b : r)
944 
945  dest[i * 6 + 0] = r_b[Y1];
946  dest[i * 6 + 1] = g[Y1];
947  dest[i * 6 + 2] = b_r[Y1];
948  dest[i * 6 + 3] = r_b[Y2];
949  dest[i * 6 + 4] = g[Y2];
950  dest[i * 6 + 5] = b_r[Y2];
951 #undef r_b
952 #undef b_r
953  } else if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565 ||
954  target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555 ||
955  target == AV_PIX_FMT_RGB444 || target == AV_PIX_FMT_BGR444) {
956  uint16_t *dest = (uint16_t *) _dest;
957  const uint16_t *r = (const uint16_t *) _r;
958  const uint16_t *g = (const uint16_t *) _g;
959  const uint16_t *b = (const uint16_t *) _b;
960  int dr1, dg1, db1, dr2, dg2, db2;
961 
962  if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565) {
963  dr1 = dither_2x2_8[ y & 1 ][0];
964  dg1 = dither_2x2_4[ y & 1 ][0];
965  db1 = dither_2x2_8[(y & 1) ^ 1][0];
966  dr2 = dither_2x2_8[ y & 1 ][1];
967  dg2 = dither_2x2_4[ y & 1 ][1];
968  db2 = dither_2x2_8[(y & 1) ^ 1][1];
969  } else if (target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555) {
970  dr1 = dither_2x2_8[ y & 1 ][0];
971  dg1 = dither_2x2_8[ y & 1 ][1];
972  db1 = dither_2x2_8[(y & 1) ^ 1][0];
973  dr2 = dither_2x2_8[ y & 1 ][1];
974  dg2 = dither_2x2_8[ y & 1 ][0];
975  db2 = dither_2x2_8[(y & 1) ^ 1][1];
976  } else {
977  dr1 = dither_4x4_16[ y & 3 ][0];
978  dg1 = dither_4x4_16[ y & 3 ][1];
979  db1 = dither_4x4_16[(y & 3) ^ 3][0];
980  dr2 = dither_4x4_16[ y & 3 ][1];
981  dg2 = dither_4x4_16[ y & 3 ][0];
982  db2 = dither_4x4_16[(y & 3) ^ 3][1];
983  }
984 
985  dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
986  dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
987  } else /* 8/4-bit */ {
988  uint8_t *dest = (uint8_t *) _dest;
989  const uint8_t *r = (const uint8_t *) _r;
990  const uint8_t *g = (const uint8_t *) _g;
991  const uint8_t *b = (const uint8_t *) _b;
992  int dr1, dg1, db1, dr2, dg2, db2;
993 
994  if (target == AV_PIX_FMT_RGB8 || target == AV_PIX_FMT_BGR8) {
995  const uint8_t * const d64 = dither_8x8_73[y & 7];
996  const uint8_t * const d32 = dither_8x8_32[y & 7];
997  dr1 = dg1 = d32[(i * 2 + 0) & 7];
998  db1 = d64[(i * 2 + 0) & 7];
999  dr2 = dg2 = d32[(i * 2 + 1) & 7];
1000  db2 = d64[(i * 2 + 1) & 7];
1001  } else {
1002  const uint8_t * const d64 = dither_8x8_73 [y & 7];
1003  const uint8_t * const d128 = dither_8x8_220[y & 7];
1004  dr1 = db1 = d128[(i * 2 + 0) & 7];
1005  dg1 = d64[(i * 2 + 0) & 7];
1006  dr2 = db2 = d128[(i * 2 + 1) & 7];
1007  dg2 = d64[(i * 2 + 1) & 7];
1008  }
1009 
1010  if (target == AV_PIX_FMT_RGB4 || target == AV_PIX_FMT_BGR4) {
1011  dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
1012  ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
1013  } else {
1014  dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
1015  dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
1016  }
1017  }
1018 }
1019 
1020 static av_always_inline void
1021 yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
1022  const int16_t **lumSrc, int lumFilterSize,
1023  const int16_t *chrFilter, const int16_t **chrUSrc,
1024  const int16_t **chrVSrc, int chrFilterSize,
1025  const int16_t **alpSrc, uint8_t *dest, int dstW,
1026  int y, enum AVPixelFormat target, int hasAlpha)
1027 {
1028  int i;
1029 
1030  for (i = 0; i < ((dstW + 1) >> 1); i++) {
1031  int j, A1, A2;
1032  int Y1 = 1 << 18;
1033  int Y2 = 1 << 18;
1034  int U = 1 << 18;
1035  int V = 1 << 18;
1036  const void *r, *g, *b;
1037 
1038  for (j = 0; j < lumFilterSize; j++) {
1039  Y1 += lumSrc[j][i * 2] * lumFilter[j];
1040  Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
1041  }
1042  for (j = 0; j < chrFilterSize; j++) {
1043  U += chrUSrc[j][i] * chrFilter[j];
1044  V += chrVSrc[j][i] * chrFilter[j];
1045  }
1046  Y1 >>= 19;
1047  Y2 >>= 19;
1048  U >>= 19;
1049  V >>= 19;
1050  if (hasAlpha) {
1051  A1 = 1 << 18;
1052  A2 = 1 << 18;
1053  for (j = 0; j < lumFilterSize; j++) {
1054  A1 += alpSrc[j][i * 2 ] * lumFilter[j];
1055  A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
1056  }
1057  A1 >>= 19;
1058  A2 >>= 19;
1059  if ((A1 | A2) & 0x100) {
1060  A1 = av_clip_uint8(A1);
1061  A2 = av_clip_uint8(A2);
1062  }
1063  }
1064 
1065  r = c->table_rV[V + YUVRGB_TABLE_HEADROOM];
1067  b = c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1068 
1069  yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1070  r, g, b, y, target, hasAlpha);
1071  }
1072 }
1073 
1074 static av_always_inline void
1075 yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
1076  const int16_t *ubuf[2], const int16_t *vbuf[2],
1077  const int16_t *abuf[2], uint8_t *dest, int dstW,
1078  int yalpha, int uvalpha, int y,
1079  enum AVPixelFormat target, int hasAlpha)
1080 {
1081  const int16_t *buf0 = buf[0], *buf1 = buf[1],
1082  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1083  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
1084  *abuf0 = hasAlpha ? abuf[0] : NULL,
1085  *abuf1 = hasAlpha ? abuf[1] : NULL;
1086  int yalpha1 = 4096 - yalpha;
1087  int uvalpha1 = 4096 - uvalpha;
1088  int i;
1089 
1090  for (i = 0; i < ((dstW + 1) >> 1); i++) {
1091  int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
1092  int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
1093  int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
1094  int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
1095  int A1, A2;
1096  const void *r = c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1098  *b = c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1099 
1100  if (hasAlpha) {
1101  A1 = (abuf0[i * 2 ] * yalpha1 + abuf1[i * 2 ] * yalpha) >> 19;
1102  A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
1103  A1 = av_clip_uint8(A1);
1104  A2 = av_clip_uint8(A2);
1105  }
1106 
1107  yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1108  r, g, b, y, target, hasAlpha);
1109  }
1110 }
1111 
1112 static av_always_inline void
1113 yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
1114  const int16_t *ubuf[2], const int16_t *vbuf[2],
1115  const int16_t *abuf0, uint8_t *dest, int dstW,
1116  int uvalpha, int y, enum AVPixelFormat target,
1117  int hasAlpha)
1118 {
1119  const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
1120  int i;
1121 
1122  if (uvalpha < 2048) {
1123  for (i = 0; i < ((dstW + 1) >> 1); i++) {
1124  int Y1 = (buf0[i * 2 ] + 64) >> 7;
1125  int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
1126  int U = (ubuf0[i] + 64) >> 7;
1127  int V = (vbuf0[i] + 64) >> 7;
1128  int A1, A2;
1129  const void *r = c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1131  *b = c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1132 
1133  if (hasAlpha) {
1134  A1 = abuf0[i * 2 ] * 255 + 16384 >> 15;
1135  A2 = abuf0[i * 2 + 1] * 255 + 16384 >> 15;
1136  A1 = av_clip_uint8(A1);
1137  A2 = av_clip_uint8(A2);
1138  }
1139 
1140  yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1141  r, g, b, y, target, hasAlpha);
1142  }
1143  } else {
1144  const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
1145  for (i = 0; i < ((dstW + 1) >> 1); i++) {
1146  int Y1 = (buf0[i * 2 ] + 64) >> 7;
1147  int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
1148  int U = (ubuf0[i] + ubuf1[i] + 128) >> 8;
1149  int V = (vbuf0[i] + vbuf1[i] + 128) >> 8;
1150  int A1, A2;
1151  const void *r = c->table_rV[V + YUVRGB_TABLE_HEADROOM],
1153  *b = c->table_bU[U + YUVRGB_TABLE_HEADROOM];
1154 
1155  if (hasAlpha) {
1156  A1 = (abuf0[i * 2 ] + 64) >> 7;
1157  A2 = (abuf0[i * 2 + 1] + 64) >> 7;
1158  A1 = av_clip_uint8(A1);
1159  A2 = av_clip_uint8(A2);
1160  }
1161 
1162  yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
1163  r, g, b, y, target, hasAlpha);
1164  }
1165  }
1166 }
1167 
1168 #define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1169 static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
1170  const int16_t **lumSrc, int lumFilterSize, \
1171  const int16_t *chrFilter, const int16_t **chrUSrc, \
1172  const int16_t **chrVSrc, int chrFilterSize, \
1173  const int16_t **alpSrc, uint8_t *dest, int dstW, \
1174  int y) \
1175 { \
1176  name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
1177  chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
1178  alpSrc, dest, dstW, y, fmt, hasAlpha); \
1179 }
1180 
1181 #define YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \
1182 YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
1183 static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
1184  const int16_t *ubuf[2], const int16_t *vbuf[2], \
1185  const int16_t *abuf[2], uint8_t *dest, int dstW, \
1186  int yalpha, int uvalpha, int y) \
1187 { \
1188  name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
1189  dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
1190 }
1191 
1192 #define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
1193 YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \
1194 static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
1195  const int16_t *ubuf[2], const int16_t *vbuf[2], \
1196  const int16_t *abuf0, uint8_t *dest, int dstW, \
1197  int uvalpha, int y) \
1198 { \
1199  name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
1200  dstW, uvalpha, y, fmt, hasAlpha); \
1201 }
1202 
1203 #if CONFIG_SMALL
1204 YUV2RGBWRAPPER(yuv2rgb,, 32_1, AV_PIX_FMT_RGB32_1, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1205 YUV2RGBWRAPPER(yuv2rgb,, 32, AV_PIX_FMT_RGB32, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1206 #else
1207 #if CONFIG_SWSCALE_ALPHA
1208 YUV2RGBWRAPPER(yuv2rgb,, a32_1, AV_PIX_FMT_RGB32_1, 1)
1209 YUV2RGBWRAPPER(yuv2rgb,, a32, AV_PIX_FMT_RGB32, 1)
1210 #endif
1211 YUV2RGBWRAPPER(yuv2rgb,, x32_1, AV_PIX_FMT_RGB32_1, 0)
1212 YUV2RGBWRAPPER(yuv2rgb,, x32, AV_PIX_FMT_RGB32, 0)
1213 #endif
1214 YUV2RGBWRAPPER(yuv2, rgb, rgb24, AV_PIX_FMT_RGB24, 0)
1215 YUV2RGBWRAPPER(yuv2, rgb, bgr24, AV_PIX_FMT_BGR24, 0)
1216 YUV2RGBWRAPPER(yuv2rgb,, 16, AV_PIX_FMT_RGB565, 0)
1217 YUV2RGBWRAPPER(yuv2rgb,, 15, AV_PIX_FMT_RGB555, 0)
1218 YUV2RGBWRAPPER(yuv2rgb,, 12, AV_PIX_FMT_RGB444, 0)
1219 YUV2RGBWRAPPER(yuv2rgb,, 8, AV_PIX_FMT_RGB8, 0)
1220 YUV2RGBWRAPPER(yuv2rgb,, 4, AV_PIX_FMT_RGB4, 0)
1221 YUV2RGBWRAPPER(yuv2rgb,, 4b, AV_PIX_FMT_RGB4_BYTE, 0)
1222 
1224  uint8_t *dest, int i, int Y, int A, int U, int V,
1225  int y, enum AVPixelFormat target, int hasAlpha, int err[4])
1226 {
1227  int R, G, B;
1228  int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8;
1229 
1230  Y -= c->yuv2rgb_y_offset;
1231  Y *= c->yuv2rgb_y_coeff;
1232  Y += 1 << 21;
1233  R = Y + V*c->yuv2rgb_v2r_coeff;
1234  G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
1235  B = Y + U*c->yuv2rgb_u2b_coeff;
1236  if ((R | G | B) & 0xC0000000) {
1237  R = av_clip_uintp2(R, 30);
1238  G = av_clip_uintp2(G, 30);
1239  B = av_clip_uintp2(B, 30);
1240  }
1241 
1242  switch(target) {
1243  case AV_PIX_FMT_ARGB:
1244  dest[0] = hasAlpha ? A : 255;
1245  dest[1] = R >> 22;
1246  dest[2] = G >> 22;
1247  dest[3] = B >> 22;
1248  break;
1249  case AV_PIX_FMT_RGB24:
1250  dest[0] = R >> 22;
1251  dest[1] = G >> 22;
1252  dest[2] = B >> 22;
1253  break;
1254  case AV_PIX_FMT_RGBA:
1255  dest[0] = R >> 22;
1256  dest[1] = G >> 22;
1257  dest[2] = B >> 22;
1258  dest[3] = hasAlpha ? A : 255;
1259  break;
1260  case AV_PIX_FMT_ABGR:
1261  dest[0] = hasAlpha ? A : 255;
1262  dest[1] = B >> 22;
1263  dest[2] = G >> 22;
1264  dest[3] = R >> 22;
1265  break;
1266  case AV_PIX_FMT_BGR24:
1267  dest[0] = B >> 22;
1268  dest[1] = G >> 22;
1269  dest[2] = R >> 22;
1270  break;
1271  case AV_PIX_FMT_BGRA:
1272  dest[0] = B >> 22;
1273  dest[1] = G >> 22;
1274  dest[2] = R >> 22;
1275  dest[3] = hasAlpha ? A : 255;
1276  break;
1277  case AV_PIX_FMT_BGR4_BYTE:
1278  case AV_PIX_FMT_RGB4_BYTE:
1279  case AV_PIX_FMT_BGR8:
1280  case AV_PIX_FMT_RGB8:
1281  {
1282  int r,g,b;
1283  R >>= 22;
1284  G >>= 22;
1285  B >>= 22;
1286  R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4;
1287  G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4;
1288  B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4;
1289  c->dither_error[0][i] = err[0];
1290  c->dither_error[1][i] = err[1];
1291  c->dither_error[2][i] = err[2];
1292  r = R >> (isrgb8 ? 5 : 7);
1293  g = G >> (isrgb8 ? 5 : 6);
1294  b = B >> (isrgb8 ? 6 : 7);
1295  r = av_clip(r, 0, isrgb8 ? 7 : 1);
1296  g = av_clip(g, 0, isrgb8 ? 7 : 3);
1297  b = av_clip(b, 0, isrgb8 ? 3 : 1);
1298  err[0] = R - r*(isrgb8 ? 36 : 255);
1299  err[1] = G - g*(isrgb8 ? 36 : 85);
1300  err[2] = B - b*(isrgb8 ? 85 : 255);
1301  if(target == AV_PIX_FMT_BGR4_BYTE) {
1302  dest[0] = r + 2*g + 8*b;
1303  } else if(target == AV_PIX_FMT_RGB4_BYTE) {
1304  dest[0] = b + 2*g + 8*r;
1305  } else if(target == AV_PIX_FMT_BGR8) {
1306  dest[0] = r + 8*g + 64*b;
1307  } else if(target == AV_PIX_FMT_RGB8) {
1308  dest[0] = b + 4*g + 32*r;
1309  } else
1310  av_assert2(0);
1311  break;}
1312  }
1313 }
1314 
1315 static av_always_inline void
1316 yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
1317  const int16_t **lumSrc, int lumFilterSize,
1318  const int16_t *chrFilter, const int16_t **chrUSrc,
1319  const int16_t **chrVSrc, int chrFilterSize,
1320  const int16_t **alpSrc, uint8_t *dest,
1321  int dstW, int y, enum AVPixelFormat target, int hasAlpha)
1322 {
1323  int i;
1324  int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
1325  int err[4] = {0};
1326 
1327  if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
1328  || target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8)
1329  step = 1;
1330 
1331  for (i = 0; i < dstW; i++) {
1332  int j;
1333  int Y = 1<<9;
1334  int U = (1<<9)-(128 << 19);
1335  int V = (1<<9)-(128 << 19);
1336  int A;
1337 
1338  for (j = 0; j < lumFilterSize; j++) {
1339  Y += lumSrc[j][i] * lumFilter[j];
1340  }
1341  for (j = 0; j < chrFilterSize; j++) {
1342  U += chrUSrc[j][i] * chrFilter[j];
1343  V += chrVSrc[j][i] * chrFilter[j];
1344  }
1345  Y >>= 10;
1346  U >>= 10;
1347  V >>= 10;
1348  if (hasAlpha) {
1349  A = 1 << 18;
1350  for (j = 0; j < lumFilterSize; j++) {
1351  A += alpSrc[j][i] * lumFilter[j];
1352  }
1353  A >>= 19;
1354  if (A & 0x100)
1355  A = av_clip_uint8(A);
1356  }
1357  yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1358  dest += step;
1359  }
1360  c->dither_error[0][i] = err[0];
1361  c->dither_error[1][i] = err[1];
1362  c->dither_error[2][i] = err[2];
1363 }
1364 
1365 static av_always_inline void
1367  const int16_t *ubuf[2], const int16_t *vbuf[2],
1368  const int16_t *abuf[2], uint8_t *dest, int dstW,
1369  int yalpha, int uvalpha, int y,
1370  enum AVPixelFormat target, int hasAlpha)
1371 {
1372  const int16_t *buf0 = buf[0], *buf1 = buf[1],
1373  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
1374  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
1375  *abuf0 = hasAlpha ? abuf[0] : NULL,
1376  *abuf1 = hasAlpha ? abuf[1] : NULL;
1377  int yalpha1 = 4096 - yalpha;
1378  int uvalpha1 = 4096 - uvalpha;
1379  int i;
1380  int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
1381  int err[4] = {0};
1382 
1383  if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
1384  || target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8)
1385  step = 1;
1386 
1387  for (i = 0; i < dstW; i++) {
1388  int Y = ( buf0[i] * yalpha1 + buf1[i] * yalpha ) >> 10; //FIXME rounding
1389  int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha-(128 << 19)) >> 10;
1390  int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha-(128 << 19)) >> 10;
1391  int A;
1392 
1393  if (hasAlpha) {
1394  A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha + (1<<18)) >> 19;
1395  if (A & 0x100)
1396  A = av_clip_uint8(A);
1397  }
1398 
1399  yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1400  dest += step;
1401  }
1402  c->dither_error[0][i] = err[0];
1403  c->dither_error[1][i] = err[1];
1404  c->dither_error[2][i] = err[2];
1405 }
1406 
1407 static av_always_inline void
1409  const int16_t *ubuf[2], const int16_t *vbuf[2],
1410  const int16_t *abuf0, uint8_t *dest, int dstW,
1411  int uvalpha, int y, enum AVPixelFormat target,
1412  int hasAlpha)
1413 {
1414  const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
1415  int i;
1416  int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
1417  int err[4] = {0};
1418 
1419  if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
1420  || target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8)
1421  step = 1;
1422 
1423  if (uvalpha < 2048) {
1424  for (i = 0; i < dstW; i++) {
1425  int Y = buf0[i] << 2;
1426  int U = (ubuf0[i] - (128<<7)) << 2;
1427  int V = (vbuf0[i] - (128<<7)) << 2;
1428  int A;
1429 
1430  if (hasAlpha) {
1431  A = (abuf0[i] + 64) >> 7;
1432  if (A & 0x100)
1433  A = av_clip_uint8(A);
1434  }
1435 
1436  yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1437  dest += step;
1438  }
1439  } else {
1440  const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
1441  for (i = 0; i < dstW; i++) {
1442  int Y = buf0[i] << 2;
1443  int U = (ubuf0[i] + ubuf1[i] - (128<<8)) << 1;
1444  int V = (vbuf0[i] + vbuf1[i] - (128<<8)) << 1;
1445  int A;
1446 
1447  if (hasAlpha) {
1448  A = (abuf0[i] + 64) >> 7;
1449  if (A & 0x100)
1450  A = av_clip_uint8(A);
1451  }
1452 
1453  yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
1454  dest += step;
1455  }
1456  }
1457 
1458  c->dither_error[0][i] = err[0];
1459  c->dither_error[1][i] = err[1];
1460  c->dither_error[2][i] = err[2];
1461 }
1462 
1463 #if CONFIG_SMALL
1464 YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1465 YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1466 YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1467 YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB, CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1468 #else
1469 #if CONFIG_SWSCALE_ALPHA
1470 YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA, 1)
1471 YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR, 1)
1472 YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA, 1)
1473 YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB, 1)
1474 #endif
1475 YUV2RGBWRAPPER(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA, 0)
1476 YUV2RGBWRAPPER(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR, 0)
1477 YUV2RGBWRAPPER(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA, 0)
1478 YUV2RGBWRAPPER(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB, 0)
1479 #endif
1480 YUV2RGBWRAPPER(yuv2, rgb_full, bgr24_full, AV_PIX_FMT_BGR24, 0)
1481 YUV2RGBWRAPPER(yuv2, rgb_full, rgb24_full, AV_PIX_FMT_RGB24, 0)
1482 
1483 YUV2RGBWRAPPER(yuv2, rgb_full, bgr4_byte_full, AV_PIX_FMT_BGR4_BYTE, 0)
1484 YUV2RGBWRAPPER(yuv2, rgb_full, rgb4_byte_full, AV_PIX_FMT_RGB4_BYTE, 0)
1485 YUV2RGBWRAPPER(yuv2, rgb_full, bgr8_full, AV_PIX_FMT_BGR8, 0)
1486 YUV2RGBWRAPPER(yuv2, rgb_full, rgb8_full, AV_PIX_FMT_RGB8, 0)
1487 
1488 static void
1489 yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter,
1490  const int16_t **lumSrc, int lumFilterSize,
1491  const int16_t *chrFilter, const int16_t **chrUSrc,
1492  const int16_t **chrVSrc, int chrFilterSize,
1493  const int16_t **alpSrc, uint8_t **dest,
1494  int dstW, int y)
1495 {
1497  int i;
1498  int hasAlpha = 0;
1499  uint16_t **dest16 = (uint16_t**)dest;
1500  int SH = 22 + 7 - desc->comp[0].depth_minus1;
1501 
1502  for (i = 0; i < dstW; i++) {
1503  int j;
1504  int Y = 1 << 9;
1505  int U = (1 << 9) - (128 << 19);
1506  int V = (1 << 9) - (128 << 19);
1507  int R, G, B, A;
1508 
1509  for (j = 0; j < lumFilterSize; j++)
1510  Y += lumSrc[j][i] * lumFilter[j];
1511 
1512  for (j = 0; j < chrFilterSize; j++) {
1513  U += chrUSrc[j][i] * chrFilter[j];
1514  V += chrVSrc[j][i] * chrFilter[j];
1515  }
1516 
1517  Y >>= 10;
1518  U >>= 10;
1519  V >>= 10;
1520 
1521  if (hasAlpha) {
1522  A = 1 << 18;
1523 
1524  for (j = 0; j < lumFilterSize; j++)
1525  A += alpSrc[j][i] * lumFilter[j];
1526 
1527  A >>= 19;
1528 
1529  if (A & 0x100)
1530  A = av_clip_uint8(A);
1531  }
1532 
1533  Y -= c->yuv2rgb_y_offset;
1534  Y *= c->yuv2rgb_y_coeff;
1535  Y += 1 << 21;
1536  R = Y + V * c->yuv2rgb_v2r_coeff;
1537  G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
1538  B = Y + U * c->yuv2rgb_u2b_coeff;
1539 
1540  if ((R | G | B) & 0xC0000000) {
1541  R = av_clip_uintp2(R, 30);
1542  G = av_clip_uintp2(G, 30);
1543  B = av_clip_uintp2(B, 30);
1544  }
1545 
1546  if (SH != 22) {
1547  dest16[0][i] = G >> SH;
1548  dest16[1][i] = B >> SH;
1549  dest16[2][i] = R >> SH;
1550  } else {
1551  dest[0][i] = G >> 22;
1552  dest[1][i] = B >> 22;
1553  dest[2][i] = R >> 22;
1554  }
1555  }
1556  if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
1557  for (i = 0; i < dstW; i++) {
1558  dest16[0][i] = av_bswap16(dest16[0][i]);
1559  dest16[1][i] = av_bswap16(dest16[1][i]);
1560  dest16[2][i] = av_bswap16(dest16[2][i]);
1561  }
1562  }
1563 }
1564 
1566  yuv2planar1_fn *yuv2plane1,
1567  yuv2planarX_fn *yuv2planeX,
1568  yuv2interleavedX_fn *yuv2nv12cX,
1569  yuv2packed1_fn *yuv2packed1,
1570  yuv2packed2_fn *yuv2packed2,
1571  yuv2packedX_fn *yuv2packedX,
1572  yuv2anyX_fn *yuv2anyX)
1573 {
1574  enum AVPixelFormat dstFormat = c->dstFormat;
1575  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
1576 
1577  if (is16BPS(dstFormat)) {
1578  *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c : yuv2planeX_16LE_c;
1579  *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c : yuv2plane1_16LE_c;
1580  } else if (is9_OR_10BPS(dstFormat)) {
1581  if (desc->comp[0].depth_minus1 == 8) {
1582  *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c : yuv2planeX_9LE_c;
1583  *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c : yuv2plane1_9LE_c;
1584  } else if (desc->comp[0].depth_minus1 == 9) {
1585  *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c : yuv2planeX_10LE_c;
1586  *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c : yuv2plane1_10LE_c;
1587  } else if (desc->comp[0].depth_minus1 == 11) {
1588  *yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_c : yuv2planeX_12LE_c;
1589  *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_c : yuv2plane1_12LE_c;
1590  } else if (desc->comp[0].depth_minus1 == 13) {
1591  *yuv2planeX = isBE(dstFormat) ? yuv2planeX_14BE_c : yuv2planeX_14LE_c;
1592  *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_c : yuv2plane1_14LE_c;
1593  } else
1594  av_assert0(0);
1595  } else {
1596  *yuv2plane1 = yuv2plane1_8_c;
1597  *yuv2planeX = yuv2planeX_8_c;
1598  if (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)
1599  *yuv2nv12cX = yuv2nv12cX_c;
1600  }
1601 
1602  if(c->flags & SWS_FULL_CHR_H_INT) {
1603  switch (dstFormat) {
1604  case AV_PIX_FMT_RGBA:
1605 #if CONFIG_SMALL
1606  *yuv2packedX = yuv2rgba32_full_X_c;
1607  *yuv2packed2 = yuv2rgba32_full_2_c;
1608  *yuv2packed1 = yuv2rgba32_full_1_c;
1609 #else
1610 #if CONFIG_SWSCALE_ALPHA
1611  if (c->alpPixBuf) {
1612  *yuv2packedX = yuv2rgba32_full_X_c;
1613  *yuv2packed2 = yuv2rgba32_full_2_c;
1614  *yuv2packed1 = yuv2rgba32_full_1_c;
1615  } else
1616 #endif /* CONFIG_SWSCALE_ALPHA */
1617  {
1618  *yuv2packedX = yuv2rgbx32_full_X_c;
1619  *yuv2packed2 = yuv2rgbx32_full_2_c;
1620  *yuv2packed1 = yuv2rgbx32_full_1_c;
1621  }
1622 #endif /* !CONFIG_SMALL */
1623  break;
1624  case AV_PIX_FMT_ARGB:
1625 #if CONFIG_SMALL
1626  *yuv2packedX = yuv2argb32_full_X_c;
1627  *yuv2packed2 = yuv2argb32_full_2_c;
1628  *yuv2packed1 = yuv2argb32_full_1_c;
1629 #else
1630 #if CONFIG_SWSCALE_ALPHA
1631  if (c->alpPixBuf) {
1632  *yuv2packedX = yuv2argb32_full_X_c;
1633  *yuv2packed2 = yuv2argb32_full_2_c;
1634  *yuv2packed1 = yuv2argb32_full_1_c;
1635  } else
1636 #endif /* CONFIG_SWSCALE_ALPHA */
1637  {
1638  *yuv2packedX = yuv2xrgb32_full_X_c;
1639  *yuv2packed2 = yuv2xrgb32_full_2_c;
1640  *yuv2packed1 = yuv2xrgb32_full_1_c;
1641  }
1642 #endif /* !CONFIG_SMALL */
1643  break;
1644  case AV_PIX_FMT_BGRA:
1645 #if CONFIG_SMALL
1646  *yuv2packedX = yuv2bgra32_full_X_c;
1647  *yuv2packed2 = yuv2bgra32_full_2_c;
1648  *yuv2packed1 = yuv2bgra32_full_1_c;
1649 #else
1650 #if CONFIG_SWSCALE_ALPHA
1651  if (c->alpPixBuf) {
1652  *yuv2packedX = yuv2bgra32_full_X_c;
1653  *yuv2packed2 = yuv2bgra32_full_2_c;
1654  *yuv2packed1 = yuv2bgra32_full_1_c;
1655  } else
1656 #endif /* CONFIG_SWSCALE_ALPHA */
1657  {
1658  *yuv2packedX = yuv2bgrx32_full_X_c;
1659  *yuv2packed2 = yuv2bgrx32_full_2_c;
1660  *yuv2packed1 = yuv2bgrx32_full_1_c;
1661  }
1662 #endif /* !CONFIG_SMALL */
1663  break;
1664  case AV_PIX_FMT_ABGR:
1665 #if CONFIG_SMALL
1666  *yuv2packedX = yuv2abgr32_full_X_c;
1667  *yuv2packed2 = yuv2abgr32_full_2_c;
1668  *yuv2packed1 = yuv2abgr32_full_1_c;
1669 #else
1670 #if CONFIG_SWSCALE_ALPHA
1671  if (c->alpPixBuf) {
1672  *yuv2packedX = yuv2abgr32_full_X_c;
1673  *yuv2packed2 = yuv2abgr32_full_2_c;
1674  *yuv2packed1 = yuv2abgr32_full_1_c;
1675  } else
1676 #endif /* CONFIG_SWSCALE_ALPHA */
1677  {
1678  *yuv2packedX = yuv2xbgr32_full_X_c;
1679  *yuv2packed2 = yuv2xbgr32_full_2_c;
1680  *yuv2packed1 = yuv2xbgr32_full_1_c;
1681  }
1682 #endif /* !CONFIG_SMALL */
1683  break;
1684  case AV_PIX_FMT_RGB24:
1685  *yuv2packedX = yuv2rgb24_full_X_c;
1686  *yuv2packed2 = yuv2rgb24_full_2_c;
1687  *yuv2packed1 = yuv2rgb24_full_1_c;
1688  break;
1689  case AV_PIX_FMT_BGR24:
1690  *yuv2packedX = yuv2bgr24_full_X_c;
1691  *yuv2packed2 = yuv2bgr24_full_2_c;
1692  *yuv2packed1 = yuv2bgr24_full_1_c;
1693  break;
1694  case AV_PIX_FMT_BGR4_BYTE:
1695  *yuv2packedX = yuv2bgr4_byte_full_X_c;
1696  *yuv2packed2 = yuv2bgr4_byte_full_2_c;
1697  *yuv2packed1 = yuv2bgr4_byte_full_1_c;
1698  break;
1699  case AV_PIX_FMT_RGB4_BYTE:
1700  *yuv2packedX = yuv2rgb4_byte_full_X_c;
1701  *yuv2packed2 = yuv2rgb4_byte_full_2_c;
1702  *yuv2packed1 = yuv2rgb4_byte_full_1_c;
1703  break;
1704  case AV_PIX_FMT_BGR8:
1705  *yuv2packedX = yuv2bgr8_full_X_c;
1706  *yuv2packed2 = yuv2bgr8_full_2_c;
1707  *yuv2packed1 = yuv2bgr8_full_1_c;
1708  break;
1709  case AV_PIX_FMT_RGB8:
1710  *yuv2packedX = yuv2rgb8_full_X_c;
1711  *yuv2packed2 = yuv2rgb8_full_2_c;
1712  *yuv2packed1 = yuv2rgb8_full_1_c;
1713  break;
1714  case AV_PIX_FMT_GBRP:
1715  case AV_PIX_FMT_GBRP9BE:
1716  case AV_PIX_FMT_GBRP9LE:
1717  case AV_PIX_FMT_GBRP10BE:
1718  case AV_PIX_FMT_GBRP10LE:
1719  case AV_PIX_FMT_GBRP12BE:
1720  case AV_PIX_FMT_GBRP12LE:
1721  case AV_PIX_FMT_GBRP14BE:
1722  case AV_PIX_FMT_GBRP14LE:
1723  case AV_PIX_FMT_GBRP16BE:
1724  case AV_PIX_FMT_GBRP16LE:
1725  *yuv2anyX = yuv2gbrp_full_X_c;
1726  break;
1727  }
1728  if (!*yuv2packedX && !*yuv2anyX)
1729  goto YUV_PACKED;
1730  } else {
1731  YUV_PACKED:
1732  switch (dstFormat) {
1733  case AV_PIX_FMT_RGB48LE:
1734  *yuv2packed1 = yuv2rgb48le_1_c;
1735  *yuv2packed2 = yuv2rgb48le_2_c;
1736  *yuv2packedX = yuv2rgb48le_X_c;
1737  break;
1738  case AV_PIX_FMT_RGB48BE:
1739  *yuv2packed1 = yuv2rgb48be_1_c;
1740  *yuv2packed2 = yuv2rgb48be_2_c;
1741  *yuv2packedX = yuv2rgb48be_X_c;
1742  break;
1743  case AV_PIX_FMT_BGR48LE:
1744  *yuv2packed1 = yuv2bgr48le_1_c;
1745  *yuv2packed2 = yuv2bgr48le_2_c;
1746  *yuv2packedX = yuv2bgr48le_X_c;
1747  break;
1748  case AV_PIX_FMT_BGR48BE:
1749  *yuv2packed1 = yuv2bgr48be_1_c;
1750  *yuv2packed2 = yuv2bgr48be_2_c;
1751  *yuv2packedX = yuv2bgr48be_X_c;
1752  break;
1753  case AV_PIX_FMT_RGB32:
1754  case AV_PIX_FMT_BGR32:
1755 #if CONFIG_SMALL
1756  *yuv2packed1 = yuv2rgb32_1_c;
1757  *yuv2packed2 = yuv2rgb32_2_c;
1758  *yuv2packedX = yuv2rgb32_X_c;
1759 #else
1760 #if CONFIG_SWSCALE_ALPHA
1761  if (c->alpPixBuf) {
1762  *yuv2packed1 = yuv2rgba32_1_c;
1763  *yuv2packed2 = yuv2rgba32_2_c;
1764  *yuv2packedX = yuv2rgba32_X_c;
1765  } else
1766 #endif /* CONFIG_SWSCALE_ALPHA */
1767  {
1768  *yuv2packed1 = yuv2rgbx32_1_c;
1769  *yuv2packed2 = yuv2rgbx32_2_c;
1770  *yuv2packedX = yuv2rgbx32_X_c;
1771  }
1772 #endif /* !CONFIG_SMALL */
1773  break;
1774  case AV_PIX_FMT_RGB32_1:
1775  case AV_PIX_FMT_BGR32_1:
1776 #if CONFIG_SMALL
1777  *yuv2packed1 = yuv2rgb32_1_1_c;
1778  *yuv2packed2 = yuv2rgb32_1_2_c;
1779  *yuv2packedX = yuv2rgb32_1_X_c;
1780 #else
1781 #if CONFIG_SWSCALE_ALPHA
1782  if (c->alpPixBuf) {
1783  *yuv2packed1 = yuv2rgba32_1_1_c;
1784  *yuv2packed2 = yuv2rgba32_1_2_c;
1785  *yuv2packedX = yuv2rgba32_1_X_c;
1786  } else
1787 #endif /* CONFIG_SWSCALE_ALPHA */
1788  {
1789  *yuv2packed1 = yuv2rgbx32_1_1_c;
1790  *yuv2packed2 = yuv2rgbx32_1_2_c;
1791  *yuv2packedX = yuv2rgbx32_1_X_c;
1792  }
1793 #endif /* !CONFIG_SMALL */
1794  break;
1795  case AV_PIX_FMT_RGB24:
1796  *yuv2packed1 = yuv2rgb24_1_c;
1797  *yuv2packed2 = yuv2rgb24_2_c;
1798  *yuv2packedX = yuv2rgb24_X_c;
1799  break;
1800  case AV_PIX_FMT_BGR24:
1801  *yuv2packed1 = yuv2bgr24_1_c;
1802  *yuv2packed2 = yuv2bgr24_2_c;
1803  *yuv2packedX = yuv2bgr24_X_c;
1804  break;
1805  case AV_PIX_FMT_RGB565LE:
1806  case AV_PIX_FMT_RGB565BE:
1807  case AV_PIX_FMT_BGR565LE:
1808  case AV_PIX_FMT_BGR565BE:
1809  *yuv2packed1 = yuv2rgb16_1_c;
1810  *yuv2packed2 = yuv2rgb16_2_c;
1811  *yuv2packedX = yuv2rgb16_X_c;
1812  break;
1813  case AV_PIX_FMT_RGB555LE:
1814  case AV_PIX_FMT_RGB555BE:
1815  case AV_PIX_FMT_BGR555LE:
1816  case AV_PIX_FMT_BGR555BE:
1817  *yuv2packed1 = yuv2rgb15_1_c;
1818  *yuv2packed2 = yuv2rgb15_2_c;
1819  *yuv2packedX = yuv2rgb15_X_c;
1820  break;
1821  case AV_PIX_FMT_RGB444LE:
1822  case AV_PIX_FMT_RGB444BE:
1823  case AV_PIX_FMT_BGR444LE:
1824  case AV_PIX_FMT_BGR444BE:
1825  *yuv2packed1 = yuv2rgb12_1_c;
1826  *yuv2packed2 = yuv2rgb12_2_c;
1827  *yuv2packedX = yuv2rgb12_X_c;
1828  break;
1829  case AV_PIX_FMT_RGB8:
1830  case AV_PIX_FMT_BGR8:
1831  *yuv2packed1 = yuv2rgb8_1_c;
1832  *yuv2packed2 = yuv2rgb8_2_c;
1833  *yuv2packedX = yuv2rgb8_X_c;
1834  break;
1835  case AV_PIX_FMT_RGB4:
1836  case AV_PIX_FMT_BGR4:
1837  *yuv2packed1 = yuv2rgb4_1_c;
1838  *yuv2packed2 = yuv2rgb4_2_c;
1839  *yuv2packedX = yuv2rgb4_X_c;
1840  break;
1841  case AV_PIX_FMT_RGB4_BYTE:
1842  case AV_PIX_FMT_BGR4_BYTE:
1843  *yuv2packed1 = yuv2rgb4b_1_c;
1844  *yuv2packed2 = yuv2rgb4b_2_c;
1845  *yuv2packedX = yuv2rgb4b_X_c;
1846  break;
1847  }
1848  }
1849  switch (dstFormat) {
1850  case AV_PIX_FMT_MONOWHITE:
1851  *yuv2packed1 = yuv2monowhite_1_c;
1852  *yuv2packed2 = yuv2monowhite_2_c;
1853  *yuv2packedX = yuv2monowhite_X_c;
1854  break;
1855  case AV_PIX_FMT_MONOBLACK:
1856  *yuv2packed1 = yuv2monoblack_1_c;
1857  *yuv2packed2 = yuv2monoblack_2_c;
1858  *yuv2packedX = yuv2monoblack_X_c;
1859  break;
1860  case AV_PIX_FMT_YUYV422:
1861  *yuv2packed1 = yuv2yuyv422_1_c;
1862  *yuv2packed2 = yuv2yuyv422_2_c;
1863  *yuv2packedX = yuv2yuyv422_X_c;
1864  break;
1865  case AV_PIX_FMT_UYVY422:
1866  *yuv2packed1 = yuv2uyvy422_1_c;
1867  *yuv2packed2 = yuv2uyvy422_2_c;
1868  *yuv2packedX = yuv2uyvy422_X_c;
1869  break;
1870  }
1871 }
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:85
int16_t ** alpPixBuf
Ring buffer for scaled horizontal alpha plane lines to be fed to the vertical scaler.
static av_always_inline void yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0, const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:1113
float v
av_cold void ff_sws_init_output_funcs(SwsContext *c, yuv2planar1_fn *yuv2plane1, yuv2planarX_fn *yuv2planeX, yuv2interleavedX_fn *yuv2nv12cX, yuv2packed1_fn *yuv2packed1, yuv2packed2_fn *yuv2packed2, yuv2packedX_fn *yuv2packedX, yuv2anyX_fn *yuv2anyX)
Definition: output.c:1565
static int shift(int a, int b)
Definition: sonic.c:86
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
#define YUVRGB_TABLE_HEADROOM
#define A1
Definition: binkdsp.c:30
#define B
Definition: dsputil.c:2025
const uint8_t dither_4x4_16[5][8]
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in ...
Definition: pixfmt.h:88
#define accumulate_bit(acc, val)
Definition: output.c:315
int acc
Definition: yuv2rgb.c:519
static av_always_inline void yuv2rgb_full_1_c_template(SwsContext *c, const int16_t *buf0, const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:1408
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 ...
Definition: pixfmt.h:117
uint8_t * table_bU[256+2 *YUVRGB_TABLE_HEADROOM]
#define av_bswap16
Definition: sh4/bswap.h:31
#define SWS_FULL_CHR_H_INT
Definition: swscale.h:79
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
external API header
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
Definition: pixfmt.h:120
planar GBR 4:4:4 36bpp, little-endian
Definition: pixfmt.h:234
packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 ...
Definition: pixfmt.h:138
the sinusoids Y1
Definition: lab5.m:33
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:270
planar GBR 4:4:4 36bpp, big-endian
Definition: pixfmt.h:233
static av_always_inline void yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW, int big_endian, int output_bits)
Definition: output.c:145
#define r_b
static av_always_inline void yuv2planeX_16_c_template(const int16_t *filter, int filterSize, const int32_t **src, uint16_t *dest, int dstW, int big_endian, int output_bits)
Definition: output.c:159
packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in ...
Definition: pixfmt.h:91
#define output_pixels(pos, Y1, U, Y2, V)
Definition: output.c:524
Macro definitions for various function/variable attributes.
#define b_r
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:115
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:89
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:86
uint8_t
#define av_cold
Definition: attributes.h:78
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:63
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:112
#define Y
Definition: vf_boxblur.c:76
#define b
Definition: input.c:42
packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 ...
Definition: pixfmt.h:137
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:114
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:98
static av_always_inline void yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0, const int32_t *ubuf[2], const int32_t *vbuf[2], const int32_t *abuf0, uint16_t *dest, int dstW, int uvalpha, int y, enum AVPixelFormat target)
Definition: output.c:778
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
static void yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t **dest, int dstW, int y)
Definition: output.c:1489
static av_always_inline void yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2], const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y, enum AVPixelFormat target)
Definition: output.c:577
#define R
Definition: dsputil.c:2027
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:173
void(* yuv2planar1_fn)(const int16_t *src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output without any additional vertical scaling (...
static av_always_inline void yuv2rgb_full_2_c_template(SwsContext *c, const int16_t *buf[2], const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:1366
external API header
static av_always_inline void yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:1316
enum AVPixelFormat dstFormat
Destination pixel format.
uint8_t * table_gU[256+2 *YUVRGB_TABLE_HEADROOM]
#define A(x)
Y2
Definition: lab5.m:34
int * dither_error[4]
#define U(x)
planar GBR 4:4:4 27bpp, big-endian
Definition: pixfmt.h:169
#define A2
Definition: binkdsp.c:31
#define B_R
Definition: output.c:668
uint16_t depth_minus1
number of bits in the component minus 1
Definition: pixdesc.h:43
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:262
const uint8_t * d64
Definition: yuv2rgb.c:487
const uint8_t dither_8x8_73[9][8]
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:99
const uint8_t dither_8x8_32[9][8]
const char * r
Definition: vf_curves.c:94
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:93
simple assert() macros that are a bit more flexible than ISO C assert().
static av_always_inline void yuv2planeX_10_c_template(const int16_t *filter, int filterSize, const int16_t **src, uint16_t *dest, int dstW, int big_endian, int output_bits)
Definition: output.c:207
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
#define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t)
Definition: output.c:227
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:96
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:143
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:97
static av_always_inline void yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2], const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y, enum AVPixelFormat target)
Definition: output.c:379
static av_always_inline void yuv2422_1_c_template(SwsContext *c, const int16_t *buf0, const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, int y, enum AVPixelFormat target)
Definition: output.c:608
as above, but U and V bytes are swapped
Definition: pixfmt.h:94
#define V
#define SWS_ERROR_DIFFUSION
Definition: swscale.h:85
FFT buffer for g
Definition: stft_peak.m:17
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:92
static av_always_inline void yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0, const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, int y, enum AVPixelFormat target)
Definition: output.c:439
static av_always_inline int is9_OR_10BPS(enum AVPixelFormat pix_fmt)
static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Definition: output.c:269
int32_t
int table_gV[256+2 *YUVRGB_TABLE_HEADROOM]
float u
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:71
static av_always_inline void yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter, const int32_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int32_t **chrUSrc, const int32_t **chrVSrc, int chrFilterSize, const int32_t **alpSrc, uint16_t *dest, int dstW, int y, enum AVPixelFormat target)
Definition: output.c:677
uint8_t * table_rV[256+2 *YUVRGB_TABLE_HEADROOM]
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:142
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
Definition: pixfmt.h:119
DECLARE_ALIGNED(8, const uint8_t, dither_2x2_4)[][8]
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:273
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:261
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:87
dest
Definition: start.py:60
AVS_Value src
Definition: avisynth_c.h:523
void(* yuv2packedX_fn)(struct SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing multi-point ver...
static av_always_inline void yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y, enum AVPixelFormat target)
Definition: output.c:326
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
planar GBR 4:4:4 30bpp, big-endian
Definition: pixfmt.h:171
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:259
void(* yuv2packed1_fn)(struct SwsContext *c, const int16_t *lumSrc, const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc, uint8_t *dest, int dstW, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output without any additional v...
static av_always_inline void yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2], const int16_t *ubuf[2], const int16_t *vbuf[2], const int16_t *abuf[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:1075
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:69
planar GBR 4:4:4 42bpp, little-endian
Definition: pixfmt.h:236
void * buf
Definition: avisynth_c.h:594
synthesis window for stochastic i
static av_always_inline void yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y, enum AVPixelFormat target)
Definition: output.c:538
void(* yuv2planarX_fn)(const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, int dstW, const uint8_t *dither, int offset)
Write one line of horizontally scaled data to planar output with multi-point vertical scaling between...
byte swapping routines
planar GBR 4:4:4 42bpp, big-endian
Definition: pixfmt.h:235
static av_always_inline void yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2, unsigned A1, unsigned A2, const void *_r, const void *_g, const void *_b, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:908
packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 ...
Definition: pixfmt.h:122
#define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha)
Definition: output.c:1192
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:272
const uint8_t * chrDither8
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 ...
Definition: pixfmt.h:116
packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1 ...
Definition: pixfmt.h:140
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:78
#define CONFIG_SWSCALE_ALPHA
Definition: config.h:394
const uint8_t dither_2x2_4[3][8]
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:77
static av_always_inline void yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t *dest, int dstW, int y, enum AVPixelFormat target, int hasAlpha)
Definition: output.c:1021
planar GBR 4:4:4 27bpp, little-endian
Definition: pixfmt.h:170
static double c[64]
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:111
#define AV_PIX_FMT_BGR444
Definition: pixfmt.h:274
void(* yuv2packed2_fn)(struct SwsContext *c, const int16_t *lumSrc[2], const int16_t *chrUSrc[2], const int16_t *chrVSrc[2], const int16_t *alpSrc[2], uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
Write one line of horizontally scaled Y/U/V/A to packed-pixel YUV/RGB output by doing bilinear scalin...
#define output_pixel(pos, val, bias, signedness)
Definition: output.c:669
const uint8_t * d128
Definition: yuv2rgb.c:518
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:90
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:269
function y
Definition: D.m:1
static av_always_inline void yuv2rgb_write_full(SwsContext *c, uint8_t *dest, int i, int Y, int A, int U, int V, int y, enum AVPixelFormat target, int hasAlpha, int err[4])
Definition: output.c:1223
#define YUV2PACKED16WRAPPER(name, base, ext, fmt)
Definition: output.c:848
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:260
static av_always_inline void yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW, int big_endian, int output_bits)
Definition: output.c:194
void(* yuv2interleavedX_fn)(struct SwsContext *c, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest, int dstW)
Write one line of horizontally scaled chroma to interleaved output with multi-point vertical scaling ...
static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest, int chrDstW)
Definition: output.c:279
static av_always_inline void yuv2rgb48_2_c_template(SwsContext *c, const int32_t *buf[2], const int32_t *ubuf[2], const int32_t *vbuf[2], const int32_t *abuf[2], uint16_t *dest, int dstW, int yalpha, int uvalpha, int y, enum AVPixelFormat target)
Definition: output.c:736
void(* yuv2anyX_fn)(struct SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize, const int16_t **alpSrc, uint8_t **dest, int dstW, int y)
Write one line of horizontally scaled Y/U/V/A to YUV/RGB output by doing multi-point vertical scaling...
const uint8_t dither_8x8_220[9][8]
#define G
Definition: dsputil.c:2026
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:268
const uint8_t dither_2x2_8[3][8]
packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 ...
Definition: pixfmt.h:121
#define R_B
Definition: output.c:667
#define av_always_inline
Definition: attributes.h:41
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:174
const uint8_t * d32
Definition: yuv2rgb.c:486
packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1 ...
Definition: pixfmt.h:139
#define HAVE_BIGENDIAN
Definition: config.h:116
#define YUV2PACKEDWRAPPER(name, base, ext, fmt)
Definition: output.c:489
int flags
Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
planar GBR 4:4:4 30bpp, little-endian
Definition: pixfmt.h:172
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step