ReactOS  0.4.15-dev-5455-g015cd25
yuv.c
Go to the documentation of this file.
1 /* DirectShow capture services (QCAP.DLL)
2  *
3  * Copyright 2005 Maarten Lankhorst
4  *
5  * This file contains the part of the vfw capture interface that
6  * does the actual Video4Linux(1/2) stuff required for capturing
7  * and setting/getting media format..
8  *
9  * This library 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  * This library 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 this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include "config.h"
25 #include <stdarg.h>
26 
27 #include "windef.h"
28 #include "wingdi.h"
29 #include "objbase.h"
30 #include "strmif.h"
31 #include "qcap_main.h"
32 #include "wine/debug.h"
33 
34 /* This is not used if V4L support is missing */
35 #if defined(HAVE_LINUX_VIDEODEV_H) || defined(HAVE_LIBV4L1_H)
36 
38 
39 static int yuv_xy[256]; /* Gray value */
40 static int yuv_gu[256]; /* Green U */
41 static int yuv_bu[256]; /* Blue U */
42 static int yuv_rv[256]; /* Red V */
43 static int yuv_gv[256]; /* Green V */
44 static BOOL initialised = FALSE;
45 
46 static inline int ValidRange(int in) {
47  if (in > 255) in = 255;
48  if (in < 0) in = 0;
49  return in;
50 }
51 
52 typedef struct RGB {
53 #if 0 /* For some reason I have to revert R and B, not sure why */
54  unsigned char r, g, b;
55 #else
56  unsigned char b, g, r;
57 #endif
58 } RGB;
59 
60 static inline void YUV2RGB(const unsigned char y_, const unsigned char cb, const unsigned char cr, RGB* retval) {
61  retval->r = ValidRange(yuv_xy[y_] + yuv_rv[cr]);
62  retval->g = ValidRange(yuv_xy[y_] + yuv_gu[cb] + yuv_gv[cr]);
63  retval->b = ValidRange(yuv_xy[y_] + yuv_bu[cb]);
64 }
65 
66 void YUV_Init(void) {
67  float y, u, v;
68  int y_, cb, cr;
69 
70  if (initialised) return;
71  initialised = TRUE;
72 
73  for (y_ = 0; y_ <= 255; y_++)
74  {
75  y = ((float) 255 / 219) * (y_ - 16);
76  yuv_xy[y_] = y;
77  }
78 
79  for (cb = 0; cb <= 255; cb++)
80  {
81  u = ((float) 255 / 224) * (cb - 128);
82  yuv_gu[cb] = -0.344 * u;
83  yuv_bu[cb] = 1.772 * u;
84  }
85 
86  for (cr = 0; cr <= 255; cr++)
87  {
88  v = ((float) 255 / 224) * (cr - 128);
89  yuv_rv[cr] = 1.402 * v;
90  yuv_gv[cr] = -0.714 * v;
91  }
92  TRACE("Filled hash table\n");
93 }
94 
95 static void Parse_YUYV(unsigned char *destbuffer, const unsigned char *input, int width, int height)
96 {
97  const unsigned char *pY, *pCb, *pCr;
98  int togo = width * height / 2;
99  pY = input;
100  pCb = input+1;
101  pCr = input+3;
102  while (--togo) {
103  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
104  pY += 2; destbuffer += 3;
105  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
106  pY += 2; pCb += 4; pCr += 4; destbuffer += 3;
107  }
108 }
109 
110 static void Parse_UYVY(unsigned char *destbuffer, const unsigned char *input, int width, int height)
111 {
112  const unsigned char *pY, *pCb, *pCr;
113  int togo = width * height / 2;
114  pY = input+1;
115  pCb = input;
116  pCr = input+2;
117  while (--togo) {
118  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
119  pY += 2; destbuffer += 3;
120  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
121  pY += 2; pCb += 4; pCr += 4; destbuffer += 3;
122  }
123 }
124 
125 static void Parse_UYYVYY(unsigned char *destbuffer, const unsigned char *input, int width, int height)
126 {
127  const unsigned char *pY, *pCb, *pCr;
128  int togo = width * height / 4;
129  pY = input+1;
130  pCb = input;
131  pCr = input+4;
132  while (--togo) {
133  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
134  destbuffer += 3; pY++;
135  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
136  pY += 2; destbuffer += 3;
137  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
138  destbuffer += 3; pY++;
139  YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
140  pY += 2; pCb += 6; pCr += 6; destbuffer += 3;
141  }
142 }
143 
144 static void Parse_PYUV(unsigned char *destbuffer, const unsigned char *input, int width, int height, int wstep, int hstep)
145 {
146  /* We have 3 pointers, One to Y, one to Cb and 1 to Cr */
147 
148 /* C19 *89* declaration block (Grr julliard for not allowing C99) */
149  int ysize, uvsize;
150  const unsigned char *pY, *pCb, *pCr;
151  int swstep = 0, shstep = 0;
152  int ypos = 0, xpos = 0;
153  int indexUV = 0, cUv;
154 /* End of Grr */
155 
156  ysize = width * height;
157  uvsize = (width / wstep) * (height / hstep);
158  pY = input;
159  pCb = pY + ysize;
160  pCr = pCb + uvsize;
161  /* Bottom down DIB */
162  do {
163  swstep = 0;
164  cUv = indexUV;
165  for (xpos = 0; xpos < width; xpos++) {
166  YUV2RGB(*(pY++), pCb[cUv], pCr[cUv], (RGB *)destbuffer);
167  destbuffer += 3;
168  if (++swstep == wstep) {
169  cUv++;
170  swstep = 0;
171  }
172  }
173  if (++shstep == hstep) {
174  shstep = 0;
175  indexUV = cUv;
176  }
177  } while (++ypos < height);
178 }
179 
180 void YUV_To_RGB24(enum YUV_Format format, unsigned char *target, const unsigned char *source, int width, int height) {
181  int wstep, hstep;
182  if (format < ENDPLANAR) {
183  switch (format) {
184  case YUVP_421: wstep = 2; hstep = 1; break;
185  case YUVP_422: wstep = 2; hstep = 2; break;
186  case YUVP_441: wstep = 4; hstep = 1; break;
187  case YUVP_444: wstep = 4; hstep = 4; break;
188  default: ERR("Unhandled format \"%d\"\n", format); return;
189  }
190  Parse_PYUV(target, source, width, height, wstep, hstep);
191  } else {
192  switch (format) {
193  case YUYV: Parse_YUYV(target, source, width, height); return;
194  case UYVY: Parse_UYVY(target, source, width, height); return;
195  case UYYVYY: Parse_UYYVYY(target, source, width, height); return;
196  default: ERR("Unhandled format \"%d\"\n", format); return;
197  }
198  }
199 }
200 #endif
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLint GLint GLsizei width
Definition: gl.h:1546
#define RGB(r, g, b)
Definition: precomp.h:62
#define TRUE
Definition: types.h:120
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define b
Definition: ke_i.h:79
GLboolean GLboolean g
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
void YUV_Init(void) DECLSPEC_HIDDEN
YUV_Format
Definition: qcap_main.h:43
Definition: qcap_main.h:54
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define ERR(fmt,...)
Definition: debug.h:110
GLenum GLenum GLenum input
Definition: glext.h:9031
const GLdouble * v
Definition: gl.h:2040
GLuint in
Definition: glext.h:9616
static float(__cdecl *square_half_float)(float x
Definition: qcap_main.h:55
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
GLenum target
Definition: glext.h:7315
void YUV_To_RGB24(enum YUV_Format format, unsigned char *target, const unsigned char *source, int width, int height) DECLSPEC_HIDDEN
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23