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
|
/*-----------------------------------------------------------------
LOG
GEM - Graphics Environment for Multimedia
GemPixConvertSIMD.h
- header-file for color conversion
- this is mainly for (SIMD-)optimized routines
- part of GEM
Copyright (c) 2006 IOhannes m zmoelnig. forum::für::umläute. IEM. zmoelnig@iem.kug.ac.at
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
-----------------------------------------------------------------*/
#ifndef INCLUDE_GEMPIXCONVERT_SIMD_H_
#define INCLUDE_GEMPIXCONVERT_SIMD_H_
#include "GemPixUtil.h"
#include "GemSIMD.h"
// use formulae from http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC30
/*
* [Y] 1 [ 65.738 129.075 25.064 ] [R] [ 16]
* [U] = --- * [ -37.945 -74.494 112.439 ] * [G]+[128]
* [V] = 256 [ 112.439 -94.154 -18.285 ] [B] [128]
*
* [R] 1 [ 298.082 0.0 408.583 ] [Y] [ 16]
* [G] = --- * [ 298.082 -100.291 -208.120 ] * ([U]-[128])
* [B] = 256 [ 298.082 516.411 0.0 ] [V] [128]
*/
#define YUV_POYNTON
// here comes something to be afraid of:
// (probably it would be better to define the matrices as real constant-value matrices)
// (instead of element-wise)
#ifdef YUV_POYNTON
# define Y_OFFSET 16
# define UV_OFFSET 128
// RGB2YUV
// poynton-values rounded
# define RGB2YUV_11 66
# define RGB2YUV_12 129
# define RGB2YUV_13 25
# define RGB2YUV_21 -38
# define RGB2YUV_22 -74
# define RGB2YUV_23 112
# define RGB2YUV_31 112
# define RGB2YUV_32 -94
# define RGB2YUV_33 -18
// YUV2RGB
// (we skip _21 and _31 as they are equal to _11)
#if 0
// poynton-values rounded
# define YUV2RGB_11 298
# define YUV2RGB_12 0
# define YUV2RGB_13 409
# define YUV2RGB_22 -100
# define YUV2RGB_23 -208
# define YUV2RGB_32 516
# define YUV2RGB_33 0
#else
// this is round(256*inv(rgb2yuv/256))
// so the general error should be smaller
# define YUV2RGB_11 298
# define YUV2RGB_12 -1
# define YUV2RGB_13 409
# define YUV2RGB_22 -100
# define YUV2RGB_23 -210
# define YUV2RGB_32 519
# define YUV2RGB_33 0
#endif
#else
/* the old ones: */
# define Y_OFFSET 0
# define UV_OFFSET 128
// RGB2YUV
# define RGB2YUV_11 77
# define RGB2YUV_12 150
# define RGB2YUV_13 29
# define RGB2YUV_21 -43
# define RGB2YUV_22 -85
# define RGB2YUV_23 128
# define RGB2YUV_31 128
# define RGB2YUV_32 -107
# define RGB2YUV_33 -21
// YUV2RGB
# define YUV2RGB_11 256
# define YUV2RGB_12 0
# define YUV2RGB_13 359
# define YUV2RGB_22 -88
# define YUV2RGB_23 -183
# define YUV2RGB_32 454
# define YUV2RGB_33 0
#endif /* POYNTON */
/* AltiVec */
#ifdef __VEC__
/* there are problems on OSX10.3 with older versions of gcc, since the intrinsic code
* below freely changes between signed and unsigned short vectors
* newer versions of gcc accept this...
* LATER: fix the code (GemPixConvertAltivec:750..800)
*/
# ifdef __GNUC__
/* according to hcs it does NOT work with gcc-3.3
* for simplicity, i disable everything below gcc4
* JMZ: 20061114
*/
# if __GNUC__ < 4
# warning disabling AltiVec for older gcc: please fix me
# define NO_VECTORINT_TO_VECTORUNSIGNEDINT
# endif
# endif /* GNUC */
void RGB_to_YCbCr_altivec(unsigned char *rgbdata, size_t RGB_size,
unsigned char *pixels);
void RGBA_to_YCbCr_altivec(unsigned char *rgbadata, size_t RGBA_size,
unsigned char *pixels);
void BGR_to_YCbCr_altivec(unsigned char *bgrdata, size_t BGR_size,
unsigned char *pixels);
void BGRA_to_YCbCr_altivec(unsigned char *bgradata, size_t BGRA_size,
unsigned char *pixels);
void YUV422_to_BGRA_altivec(unsigned char *yuvdata, size_t pixelnum,
unsigned char *pixels);
void YV12_to_YUV422_altivec(short*Y, short*U, short*V,
unsigned char *data, int xsize, int ysize);
# ifndef NO_VECTORINT_TO_VECTORUNSIGNEDINT
void YUV422_to_YV12_altivec(short*pY, short*pY2, short*pU, short*pV,
unsigned char *gem_image, int xsize, int ysize);
# endif
#endif /* AltiVec */
/* SSE2 */
#ifdef __SSE2__
void RGBA_to_UYVY_SSE2(unsigned char *rgbadata,
size_t size,
unsigned char *yuvdata);
void UYVY_to_RGBA_SSE2(unsigned char *yuvdata,
size_t size,
unsigned char *rgbadata);
void UYVY_to_RGB_SSE2(unsigned char *yuvdata,
size_t size,
unsigned char *rgbadata);
#endif /* SSE2 */
/* in case somebody has an old machine... */
#ifdef __MMX__
#endif /* MMX */
#endif /* INCLUDE_GEMPIXCONVERT_SIMD_H_ */
|