Instrument Neutral Distributed Interface INDI  2.0.2
v4l2_colorspace.c
Go to the documentation of this file.
1 
2 #include "v4l2_colorspace.h"
3 
4 #include <math.h>
5 
6 unsigned char lutrangey8[256];
7 unsigned short lutrangey10[1024];
8 unsigned short lutrangey12[4096];
9 unsigned short lutrangey16[65536];
10 unsigned char lutrangecbcr8[256];
11 unsigned short lutrangecbcr10[1024];
12 unsigned short lutrangecbcr12[4096];
13 unsigned short lutrangecbcr16[65536];
14 
16 {
17  unsigned int i;
18 
19  for (i = 0; i < 256; i++)
20  {
21  lutrangey8[i] = (unsigned char)((255.0 / 219.0) * (i - 16));
22  if (i > 235)
23  lutrangey8[i] = 255;
24  lutrangecbcr8[i] = (unsigned char)((255.0 / 224.0) * i);
25  }
26 }
27 
28 void rangeY8(unsigned char *buf, unsigned int len)
29 {
30  unsigned char *s = buf;
31 
32  for (unsigned int i = 0; i < len; i++)
33  {
34  *s = lutrangey8[*s];
35  s++;
36  }
37 }
38 
39 void linearize(float *buf, unsigned int len, struct v4l2_format *fmt)
40 {
41  unsigned int i;
42  float *src = buf;
43  switch (fmt->fmt.pix.colorspace)
44  {
45  case V4L2_COLORSPACE_DEFAULT:
46  break;
47  case V4L2_COLORSPACE_SMPTE240M:
48  // Old obsolete HDTV standard. Replaced by REC 709.
49  // This is the transfer function for SMPTE 240M
50  for (i = 0; i < len; i++)
51  {
52  *src = (*src < 0.0913) ? *src / 4.0 : pow((*src + 0.1115) / 1.1115, 1.0 / 0.45);
53  src++;
54  }
55  break;
56  case V4L2_COLORSPACE_SRGB:
57  // This is used for sRGB as specified by the IEC FDIS 61966-2-1 standard
58  for (i = 0; i < len; i++)
59  {
60  *src = (*src < -0.04045) ? -pow((-*src + 0.055) / 1.055, 2.4) :
61  ((*src <= 0.04045) ? *src / 12.92 : pow((*src + 0.055) / 1.055, 2.4));
62  src++;
63  }
64  break;
65  //case V4L2_COLORSPACE_ADOBERGB:
66  //r = pow(r, 2.19921875);
67  //break;
68  case V4L2_COLORSPACE_REC709:
69  //case V4L2_COLORSPACE_BT2020:
70  default:
71  // All others use the transfer function specified by REC 709
72  for (i = 0; i < len; i++)
73  {
74  *src = (*src <= -0.081) ? -pow((*src - 0.099) / -1.099, 1.0 / 0.45) :
75  ((*src < 0.081) ? *src / 4.5 : pow((*src + 0.099) / 1.099, 1.0 / 0.45));
76  src++;
77  }
78  }
79 }
80 
81 const char *getColorSpaceName(struct v4l2_format *fmt)
82 {
83  switch (fmt->fmt.pix.colorspace)
84  {
85  case V4L2_COLORSPACE_SMPTE170M:
86  return "SMPTE170M (SDTV)";
87  case V4L2_COLORSPACE_SMPTE240M:
88  return "SMPTE240M (early HDTV)";
89  case V4L2_COLORSPACE_REC709:
90  return "REC709 (HDTV)";
91  case V4L2_COLORSPACE_BT878:
92  return "BT878";
93  case V4L2_COLORSPACE_470_SYSTEM_M:
94  return "470 SYSTEM M (old NTSC)";
95  case V4L2_COLORSPACE_470_SYSTEM_BG:
96  return "470 SYSTEM BG (old PAL/SECAM)";
97  case V4L2_COLORSPACE_JPEG:
98  return "JPEG";
99  case V4L2_COLORSPACE_SRGB:
100  return "SRGB";
101  /* since Kernel 3.19
102  case V4L2_COLORSPACE_ADOBERGB:
103  return "Adobe RGB";
104  case V4L2_COLORSPACE_BT2020:
105  return "BT2020 (UHDTV)";
106  */
107  default:
108  return "Unknown";
109  }
110 }
111 
112 unsigned int getYCbCrEncoding(struct v4l2_format *fmt)
113 {
114  switch (fmt->fmt.pix.colorspace)
115  {
116  case V4L2_COLORSPACE_SMPTE170M:
117  case V4L2_COLORSPACE_BT878:
118  case V4L2_COLORSPACE_470_SYSTEM_M:
119  case V4L2_COLORSPACE_470_SYSTEM_BG:
120  case V4L2_COLORSPACE_JPEG:
121  return YCBCR_ENC_601;
122  case V4L2_COLORSPACE_REC709:
123  return YCBCR_ENC_709;
124  case V4L2_COLORSPACE_SRGB:
125  return YCBCR_ENC_SYCC;
126  case V4L2_COLORSPACE_SMPTE240M:
127  return YCBCR_ENC_SMPTE240M;
128  /* since Kernel 3.19
129  case V4L2_COLORSPACE_ADOBERGB:
130  return return V4L2_YCBCR_ENC_601;
131  case V4L2_COLORSPACE_BT2020:
132  return return V4L2_YCBCR_ENC_BT2020;
133  */
134  default:
135  return YCBCR_ENC_601;
136  }
137 }
138 
139 const char *getYCbCrEncodingName(struct v4l2_format *fmt)
140 {
141  switch (getYCbCrEncoding(fmt))
142  {
143  case YCBCR_ENC_601:
144  return "ITU-R 601 -- SDTV";
145  case YCBCR_ENC_709:
146  return "Rec. 709 -- HDTV";
147  case YCBCR_ENC_SYCC:
148  return "sYCC (Y'CbCr encoding of sRGB)";
149  case YCBCR_ENC_SMPTE240M:
150  return "SMPTE 240M -- Obsolete HDTV";
151  default:
152  return "Unknown";
153  }
154 }
155 
156 unsigned int getQuantization(struct v4l2_format *fmt)
157 {
158  switch (fmt->fmt.pix.colorspace)
159  {
160  /* since Kernel 3.19
161  case V4L2_COLORSPACE_ADOBERGB:
162  case V4L2_COLORSPACE_BT2020:
163  */
164  case V4L2_COLORSPACE_SMPTE170M:
165  case V4L2_COLORSPACE_BT878:
166  case V4L2_COLORSPACE_470_SYSTEM_M:
167  case V4L2_COLORSPACE_470_SYSTEM_BG:
168  case V4L2_COLORSPACE_JPEG:
169  case V4L2_COLORSPACE_REC709:
170  case V4L2_COLORSPACE_SMPTE240M:
171  return QUANTIZATION_LIM_RANGE;
172  case V4L2_COLORSPACE_SRGB:
174  default:
175  return QUANTIZATION_LIM_RANGE;
176  }
177 }
178 
179 const char *getQuantizationName(struct v4l2_format *fmt)
180 {
181  switch (getQuantization(fmt))
182  {
184  return "Full Range";
186  return "Limited Range";
187  default:
188  return "Unknown";
189  }
190 }
unsigned char lutrangecbcr8[256]
unsigned char lutrangey8[256]
void initColorSpace()
unsigned short lutrangey10[1024]
const char * getYCbCrEncodingName(struct v4l2_format *fmt)
unsigned short lutrangey12[4096]
unsigned short lutrangecbcr12[4096]
void rangeY8(unsigned char *buf, unsigned int len)
unsigned short lutrangey16[65536]
unsigned int getQuantization(struct v4l2_format *fmt)
unsigned short lutrangecbcr16[65536]
const char * getQuantizationName(struct v4l2_format *fmt)
void linearize(float *buf, unsigned int len, struct v4l2_format *fmt)
unsigned short lutrangecbcr10[1024]
unsigned int getYCbCrEncoding(struct v4l2_format *fmt)
const char * getColorSpaceName(struct v4l2_format *fmt)
#define QUANTIZATION_FULL_RANGE
#define YCBCR_ENC_SYCC
#define YCBCR_ENC_601
#define QUANTIZATION_LIM_RANGE
#define YCBCR_ENC_709
#define YCBCR_ENC_SMPTE240M