Welcome to mirror list, hosted at ThFree Co, Russian Federation.

FilterSource.h « VideoTexture « gameengine « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a4900e8c1485ee355e5a131308c29bea639bc832 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
-----------------------------------------------------------------------------
This source file is part of blendTex library

Copyright (c) 2007 The Zdeno Ash Miklas

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/

/** \file FilterSource.h
 *  \ingroup bgevideotex
 */
 
#ifndef __FILTERSOURCE_H__
#define __FILTERSOURCE_H__

#include "Common.h"

#include "FilterBase.h"


/// class for RGB24 conversion
class FilterRGB24 : public FilterBase
{
public:
	/// constructor
	FilterRGB24 (void) {}
	/// destructor
	virtual ~FilterRGB24 (void) {}

	/// get source pixel size
	virtual unsigned int getPixelSize (void) { return 3; }

protected:
	/// filter pixel, source byte buffer
	virtual unsigned int filter (unsigned char * src, short x, short y,
		short * size, unsigned int pixSize, unsigned int val)
	{ VT_RGBA(val,src[0],src[1],src[2],0xFF); return val; }
};

/// class for RGBA32 conversion
class FilterRGBA32 : public FilterBase
{
public:
	/// constructor
	FilterRGBA32 (void) {}
	/// destructor
	virtual ~FilterRGBA32 (void) {}

	/// get source pixel size
	virtual unsigned int getPixelSize (void) { return 4; }

protected:
	/// filter pixel, source byte buffer
	virtual unsigned int filter (unsigned char * src, short x, short y,
		short * size, unsigned int pixSize, unsigned int val)
	{ 
		if ((intptr_t(src)&0x3) == 0) 
			return *(unsigned int*)src;
		else 
		{
			VT_RGBA(val,src[0],src[1],src[2],src[3]); 
			return val; 
		}
	}
};

/// class for BGR24 conversion
class FilterBGR24 : public FilterBase
{
public:
	/// constructor
	FilterBGR24 (void) {}
	/// destructor
	virtual ~FilterBGR24 (void) {}

	/// get source pixel size
	virtual unsigned int getPixelSize (void) { return 3; }

protected:
	/// filter pixel, source byte buffer
	virtual unsigned int filter (unsigned char * src, short x, short y,
		short * size, unsigned int pixSize, unsigned int val)
	{ VT_RGBA(val,src[2],src[1],src[0],0xFF); return val; }
};

/// class for YV12 conversion
class FilterYV12 : public FilterBase
{
public:
	/// constructor
	FilterYV12 (void) {}
	/// destructor
	virtual ~FilterYV12 (void) {}

	/// get source pixel size
	virtual unsigned int getPixelSize (void) { return 1; }

	/// set pointers to color buffers
	void setBuffs (unsigned char * buff, short * size)
	{
		unsigned int buffSize = size[0] * size[1];
		m_buffV = buff + buffSize;
		m_buffU = m_buffV + (buffSize >> 2);
		m_pitchUV = size[0] >> 1;
	}

protected:
	/// begin of V buffer
	unsigned char * m_buffV;
	/// begin of U buffer
	unsigned char * m_buffU;
	/// pitch for V & U buffers
	short m_pitchUV;

	/// interpolation function
	int interpol (int a, int b, int c, int d)
	{ return (9 * (b + c) - a - d + 8) >> 4; }

	/// common horizontal interpolation
	int interpolH (unsigned char * src)
	{ return interpol(*(src-1), *src, *(src+1), *(src+2)); }

	/// common vertical interpolation
	int interpolV (unsigned char * src)
	{ return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); }

	/// common joined vertical and horizontal interpolation
	int interpolVH (unsigned char * src)
	{
		return interpol(interpolV(src-1), interpolV(src), interpolV(src+1),
			interpolV(src+2));
	}

	/// is pixel on edge
	bool isEdge (short x, short y, short * size)
	{ return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; }

	/// get the first parameter on the low edge
	unsigned char * interParA (unsigned char * src, short x, short size, short shift)
	{ return x > 1 ? src - shift : src; }
	/// get the third parameter on the high edge
	unsigned char * interParC (unsigned char * src, short x, short size, short shift)
	{ return x < size - 2 ? src + shift : src; }
	/// get the fourth parameter on the high edge
	unsigned char * interParD (unsigned char * src, short x, short size, short shift)
	{ return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; }

	/// horizontal interpolation on edges
	int interpolEH (unsigned char * src, short x, short size)
	{ 
		return interpol(*interParA(src, x, size, 1), *src,
			*interParC(src, x, size, 1), *interParD(src, x, size, 1));
	}

	/// vertical interpolation on edges
	int interpolEV (unsigned char * src, short y, short size)
	{ 
		return interpol(*interParA(src, y, size, m_pitchUV), *src,
			*interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV));
	}

	/// joined vertical and horizontal interpolation on edges
	int interpolEVH (unsigned char * src, short x, short y, short * size)
	{
		return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]),
			interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]),
			interpolEV(interParD(src, x, size[0], 1), y, size[1]));
	}


	/// filter pixel, source byte buffer
	virtual unsigned int filter (unsigned char * src, short x, short y,
		short * size, unsigned int pixSize, unsigned int val)
	{
		// V & U offset
		long offset = (x >> 1) + m_pitchUV * (y >> 1);
		// get modified YUV -> CDE: C = Y - 16; D = U - 128; E = V - 128
		int c = *src - 16;
		int d = m_buffU[offset] - 128;
		int e = m_buffV[offset] - 128;
		// if horizontal interpolation is needed
		if ((x & 1) == 1) {
			// if vertical interpolation is needed too
			if ((y & 1) == 1)
			{
				// if this pixel is on the edge
				if (isEdge(x, y, size))
				{
					// get U & V from edge
					d = interpolEVH(m_buffU + offset, x, y, size) - 128;
					e = interpolEVH(m_buffV + offset, x, y, size) - 128;
				}
				// otherwise get U & V from inner range
				else
				{
					d = interpolVH(m_buffU + offset) - 128;
					e = interpolVH(m_buffV + offset) - 128;
				}
				// otherwise use horizontal interpolation only
			}
			else {
				// if this pixel is on the edge
				if (isEdge(x, y, size))
				{
					// get U & V from edge
					d = interpolEH(m_buffU + offset, x, size[0]) - 128;
					e = interpolEH(m_buffV + offset, x, size[0]) - 128;
				}
				// otherwise get U & V from inner range
				else
				{
					d = interpolH(m_buffU + offset) - 128;
					e = interpolH(m_buffV + offset) - 128;
				}
				// otherwise if only vertical interpolation is needed
			}
		}
		else if ((y & 1) == 1) {
			// if this pixel is on the edge
			if (isEdge(x, y, size))
			{
				// get U & V from edge
				d = interpolEV(m_buffU + offset, y, size[1]) - 128;
				e = interpolEV(m_buffV + offset, y, size[1]) - 128;
			}
			// otherwise get U & V from inner range
			else
			{
				d = interpolV(m_buffU + offset) - 128;
				e = interpolV(m_buffV + offset) - 128;
			}
		}
		// convert to RGB
		// R = clip(( 298 * C           + 409 * E + 128) >> 8)
		// G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
		// B = clip(( 298 * C + 516 * D           + 128) >> 8)
		int red = (298 * c + 409 * e + 128) >> 8;
		if (red >= 0x100) red = 0xFF;
		else if (red < 0) red = 0;
		int green = (298 * c - 100 * d - 208 * e) >> 8;
		if (green >= 0x100) green = 0xFF;
		else if (green < 0) green = 0;
		int blue = (298 * c + 516 * d + 128) >> 8;
		if (blue >= 0x100) blue = 0xFF;
		else if (blue < 0) blue = 0;
		// return result
		VT_RGBA(val, red, green, blue, 0xFF);
		return val;
	}
};


#endif