FFmpeg
yuv2rgb_template.c
Go to the documentation of this file.
1 /*
2  * software YUV to RGB converter
3  *
4  * Copyright (C) 2001-2007 Michael Niedermayer
5  * (c) 2010 Konstantin Shishkov
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <stdint.h>
25 
26 #include "libavutil/x86/asm.h"
28 
29 #define YUV2RGB_LOOP(depth) \
30  h_size = (c->dstW + 7) & ~7; \
31  if (h_size * depth > FFABS(dstStride[0])) \
32  h_size -= 8; \
33  \
34  vshift = c->srcFormat != AV_PIX_FMT_YUV422P; \
35  \
36  for (y = 0; y < srcSliceH; y++) { \
37  uint8_t *image = dst[0] + (y + srcSliceY) * dstStride[0]; \
38  const uint8_t *py = src[0] + y * srcStride[0]; \
39  const uint8_t *pu = src[1] + (y >> vshift) * srcStride[1]; \
40  const uint8_t *pv = src[2] + (y >> vshift) * srcStride[2]; \
41  x86_reg index = -h_size / 2; \
42 
43 extern void RENAME(ff_yuv_420_rgb24)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
44  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
45  const uint8_t *py_2index);
46 extern void RENAME(ff_yuv_420_bgr24)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
47  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
48  const uint8_t *py_2index);
49 
50 extern void RENAME(ff_yuv_420_rgb15)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
51  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
52  const uint8_t *py_2index);
53 extern void RENAME(ff_yuv_420_rgb16)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
54  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
55  const uint8_t *py_2index);
56 extern void RENAME(ff_yuv_420_rgb32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
57  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
58  const uint8_t *py_2index);
59 extern void RENAME(ff_yuv_420_bgr32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
60  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
61  const uint8_t *py_2index);
62 extern void RENAME(ff_yuva_420_rgb32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
63  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
64  const uint8_t *py_2index, const uint8_t *pa_2index);
65 extern void RENAME(ff_yuva_420_bgr32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
66  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
67  const uint8_t *py_2index, const uint8_t *pa_2index);
68 
69 static inline int RENAME(yuv420_rgb15)(SwsContext *c, const uint8_t *src[],
70  int srcStride[],
71  int srcSliceY, int srcSliceH,
72  uint8_t *dst[], int dstStride[])
73 {
74  int y, h_size, vshift;
75 
76  YUV2RGB_LOOP(2)
77 
78 #ifdef DITHER1XBPP
79  c->blueDither = ff_dither8[y & 1];
80  c->greenDither = ff_dither8[y & 1];
81  c->redDither = ff_dither8[(y + 1) & 1];
82 #endif
83 
84  RENAME(ff_yuv_420_rgb15)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
85  }
86  return srcSliceH;
87 }
88 
89 static inline int RENAME(yuv420_rgb16)(SwsContext *c, const uint8_t *src[],
90  int srcStride[],
91  int srcSliceY, int srcSliceH,
92  uint8_t *dst[], int dstStride[])
93 {
94  int y, h_size, vshift;
95 
96  YUV2RGB_LOOP(2)
97 
98 #ifdef DITHER1XBPP
99  c->blueDither = ff_dither8[y & 1];
100  c->greenDither = ff_dither4[y & 1];
101  c->redDither = ff_dither8[(y + 1) & 1];
102 #endif
103 
104  RENAME(ff_yuv_420_rgb16)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
105  }
106  return srcSliceH;
107 }
108 
109 static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[],
110  int srcStride[],
111  int srcSliceY, int srcSliceH,
112  uint8_t *dst[], int dstStride[])
113 {
114  int y, h_size, vshift;
115 
116  YUV2RGB_LOOP(4)
117 
118  RENAME(ff_yuv_420_rgb32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
119  }
120  return srcSliceH;
121 }
122 
123 static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[],
124  int srcStride[],
125  int srcSliceY, int srcSliceH,
126  uint8_t *dst[], int dstStride[])
127 {
128  int y, h_size, vshift;
129 
130  YUV2RGB_LOOP(4)
131 
132  RENAME(ff_yuv_420_bgr32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
133  }
134  return srcSliceH;
135 }
136 
137 static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[],
138  int srcStride[],
139  int srcSliceY, int srcSliceH,
140  uint8_t *dst[], int dstStride[])
141 {
142  int y, h_size, vshift;
143  YUV2RGB_LOOP(4)
144 
145  const uint8_t *pa = src[3] + y * srcStride[3];
146  RENAME(ff_yuva_420_rgb32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index, pa - 2 * index);
147  }
148  return srcSliceH;
149 }
150 
151 static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[],
152  int srcStride[],
153  int srcSliceY, int srcSliceH,
154  uint8_t *dst[], int dstStride[])
155 {
156  int y, h_size, vshift;
157 
158  YUV2RGB_LOOP(4)
159 
160  const uint8_t *pa = src[3] + y * srcStride[3];
161  RENAME(ff_yuva_420_bgr32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index, pa - 2 * index);
162  }
163  return srcSliceH;
164 }
165 
166 static inline int RENAME(yuv420_rgb24)(SwsContext *c, const uint8_t *src[],
167  int srcStride[],
168  int srcSliceY, int srcSliceH,
169  uint8_t *dst[], int dstStride[])
170 {
171  int y, h_size, vshift;
172 
173  YUV2RGB_LOOP(3)
174 
175  RENAME(ff_yuv_420_rgb24)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
176  }
177  return srcSliceH;
178 }
179 
180 static inline int RENAME(yuv420_bgr24)(SwsContext *c, const uint8_t *src[],
181  int srcStride[],
182  int srcSliceY, int srcSliceH,
183  uint8_t *dst[], int dstStride[])
184 {
185  int y, h_size, vshift;
186 
187  YUV2RGB_LOOP(3)
188 
189  RENAME(ff_yuv_420_bgr24)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
190  }
191  return srcSliceH;
192 }
x86_reg
int x86_reg
Definition: asm.h:72
YUV2RGB_LOOP
#define YUV2RGB_LOOP(depth)
Definition: yuv2rgb_template.c:29
ff_dither4
const uint64_t ff_dither4[2]
Definition: swscale.c:33
asm.h
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
srcSliceH
return srcSliceH
Definition: yuv2rgb_template.c:86
swscale_internal.h
ff_dither8
const uint64_t ff_dither8[2]
Definition: swscale.c:37
RENAME
#define RENAME(element)
Definition: ac3enc_template.c:44
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
SwsContext
Definition: swscale_internal.h:301