image.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
4 #include "image.h"
5 #include "../include/librealsense/rsutil.h" // For projection/deprojection logic
6 
7 #include <cstring> // For memcpy
8 #include <cmath>
9 #include <algorithm>
10 #ifdef __SSSE3__
11 #include <tmmintrin.h> // For SSE3 intrinsic used in unpack_yuy2_sse
12 #endif
13 
14 #pragma pack(push, 1) // All structs in this file are assumed to be byte-packed
15 namespace rsimpl
16 {
17 
19  // Image size computation //
21 
23  {
24  if (format == RS_FORMAT_YUYV) assert(width % 2 == 0);
25  if (format == RS_FORMAT_RAW10) assert(width % 4 == 0);
26  return width * height * get_image_bpp(format) / 8;
27  }
28 
30  {
31  switch (format)
32  {
33  case RS_FORMAT_Z16: return 16;
34  case RS_FORMAT_DISPARITY16: return 16;
35  case RS_FORMAT_XYZ32F: return 12 * 8;
36  case RS_FORMAT_YUYV: return 16;
37  case RS_FORMAT_RGB8: return 24;
38  case RS_FORMAT_BGR8: return 24;
39  case RS_FORMAT_RGBA8: return 32;
40  case RS_FORMAT_BGRA8: return 32;
41  case RS_FORMAT_Y8: return 8;
42  case RS_FORMAT_Y16: return 16;
43  case RS_FORMAT_RAW10: return 10;
44  case RS_FORMAT_RAW16: return 16;
45  case RS_FORMAT_RAW8: return 8;
46  default: assert(false); return 0;
47  }
48  }
50  // Naive unpacking routines //
52 
53  template<size_t SIZE> void copy_pixels(byte * const dest[], const byte * source, int count)
54  {
55  memcpy(dest[0], source, SIZE * count);
56  }
57 
58  void copy_raw10(byte * const dest[], const byte * source, int count)
59  {
60  memcpy(dest[0], source, (5 * (count/4)));
61  }
62 
63  template<class SOURCE, class UNPACK> void unpack_pixels(byte * const dest[], int count, const SOURCE * source, UNPACK unpack)
64  {
65  auto out = reinterpret_cast<decltype(unpack(SOURCE())) *>(dest[0]);
66  for(int i=0; i<count; ++i) *out++ = unpack(*source++);
67  }
68 
69  void unpack_y16_from_y8 (byte * const d[], const byte * s, int n) { unpack_pixels(d, n, reinterpret_cast<const uint8_t *>(s), [](uint8_t pixel) -> uint16_t { return pixel | pixel << 8; }); }
70  void unpack_y16_from_y16_10(byte * const d[], const byte * s, int n) { unpack_pixels(d, n, reinterpret_cast<const uint16_t *>(s), [](uint16_t pixel) -> uint16_t { return pixel << 6; }); }
71  void unpack_y8_from_y16_10 (byte * const d[], const byte * s, int n) { unpack_pixels(d, n, reinterpret_cast<const uint16_t *>(s), [](uint16_t pixel) -> uint8_t { return pixel >> 2; }); }
72  void unpack_rw10_from_rw8 (byte * const d[], const byte * s, int n)
73  {
74 #ifdef __SSSE3__
75  auto src = reinterpret_cast<const __m128i *>(s);
76  auto dst = reinterpret_cast<__m128i *>(d[0]);
77 
78  __m128i* xin = (__m128i*)src;
79  __m128i* xout = (__m128i*) dst;
80  for (int i = 0; i < n; i += 16, ++xout, xin += 2)
81  {
82  __m128i in1_16 = _mm_load_si128((__m128i*)(xin));
83  __m128i in2_16 = _mm_load_si128((__m128i*)(xin + 1));
84  __m128i out1_16 = _mm_srli_epi16(in1_16, 2);
85  __m128i out2_16 = _mm_srli_epi16(in2_16, 2);
86  __m128i out8 = _mm_packus_epi16(out1_16, out2_16);
87  _mm_store_si128(xout, out8);
88  }
89 #else // Generic code for when SSSE3 is not available.
90  unsigned short* from = (unsigned short*)s;
91  byte* to = d[0];
92 
93  for(int i = 0; i < n; ++i)
94  {
95  byte temp = (byte)(*from >> 2);
96  *to = temp;
97  ++from;
98  ++to;
99  }
100 #endif
101  }
102 
104  // YUY2 unpacking routines //
106 
107  // This templated function unpacks YUY2 into Y8/Y16/RGB8/RGBA8/BGR8/BGRA8, depending on the compile-time parameter FORMAT.
108  // It is expected that all branching outside of the loop control variable will be removed due to constant-folding.
109  template<rs_format FORMAT> void unpack_yuy2(byte * const d [], const byte * s, int n)
110  {
111  assert(n % 16 == 0); // All currently supported color resolutions are multiples of 16 pixels. Could easily extend support to other resolutions by copying final n<16 pixels into a zero-padded buffer and recursively calling self for final iteration.
112 #ifdef __SSSE3__
113  auto src = reinterpret_cast<const __m128i *>(s);
114  auto dst = reinterpret_cast<__m128i *>(d[0]);
115  for(; n; n -= 16)
116  {
117  const __m128i zero = _mm_set1_epi8(0);
118  const __m128i n100 = _mm_set1_epi16(100 << 4);
119  const __m128i n208 = _mm_set1_epi16(208 << 4);
120  const __m128i n298 = _mm_set1_epi16(298 << 4);
121  const __m128i n409 = _mm_set1_epi16(409 << 4);
122  const __m128i n516 = _mm_set1_epi16(516 << 4);
123  const __m128i evens_odds = _mm_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15);
124 
125  // Load 8 YUY2 pixels each into two 16-byte registers
126  __m128i s0 = _mm_loadu_si128(src++);
127  __m128i s1 = _mm_loadu_si128(src++);
128 
129  if(FORMAT == RS_FORMAT_Y8)
130  {
131  // Align all Y components and output 16 pixels (16 bytes) at once
132  __m128i y0 = _mm_shuffle_epi8(s0, _mm_setr_epi8(1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 14));
133  __m128i y1 = _mm_shuffle_epi8(s1, _mm_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15));
134  _mm_storeu_si128(dst++, _mm_alignr_epi8(y0, y1, 8));
135  continue;
136  }
137 
138  // Shuffle all Y components to the low order bytes of the register, and all U/V components to the high order bytes
139  const __m128i evens_odd1s_odd3s = _mm_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, 1, 5, 9, 13, 3, 7, 11, 15); // to get yyyyyyyyuuuuvvvv
140  __m128i yyyyyyyyuuuuvvvv0 = _mm_shuffle_epi8(s0, evens_odd1s_odd3s);
141  __m128i yyyyyyyyuuuuvvvv8 = _mm_shuffle_epi8(s1, evens_odd1s_odd3s);
142 
143  // Retrieve all 16 Y components as 16-bit values (8 components per register))
144  __m128i y16__0_7 = _mm_unpacklo_epi8(yyyyyyyyuuuuvvvv0, zero); // convert to 16 bit
145  __m128i y16__8_F = _mm_unpacklo_epi8(yyyyyyyyuuuuvvvv8, zero); // convert to 16 bit
146 
147  if(FORMAT == RS_FORMAT_Y16)
148  {
149  // Output 16 pixels (32 bytes) at once
150  _mm_storeu_si128(dst++, _mm_slli_epi16(y16__0_7, 8));
151  _mm_storeu_si128(dst++, _mm_slli_epi16(y16__8_F, 8));
152  continue;
153  }
154 
155  // Retrieve all 16 U and V components as 16-bit values (8 components per register)
156  __m128i uv = _mm_unpackhi_epi32(yyyyyyyyuuuuvvvv0, yyyyyyyyuuuuvvvv8); // uuuuuuuuvvvvvvvv
157  __m128i u = _mm_unpacklo_epi8(uv, uv); // uu uu uu uu uu uu uu uu u's duplicated
158  __m128i v = _mm_unpackhi_epi8(uv, uv); // vv vv vv vv vv vv vv vv
159  __m128i u16__0_7 = _mm_unpacklo_epi8(u, zero); // convert to 16 bit
160  __m128i u16__8_F = _mm_unpackhi_epi8(u, zero); // convert to 16 bit
161  __m128i v16__0_7 = _mm_unpacklo_epi8(v, zero); // convert to 16 bit
162  __m128i v16__8_F = _mm_unpackhi_epi8(v, zero); // convert to 16 bit
163 
164  // Compute R, G, B values for first 8 pixels
165  __m128i c16__0_7 = _mm_slli_epi16(_mm_subs_epi16(y16__0_7, _mm_set1_epi16(16)), 4);
166  __m128i d16__0_7 = _mm_slli_epi16(_mm_subs_epi16(u16__0_7, _mm_set1_epi16(128)), 4); // perhaps could have done these u,v to d,e before the duplication
167  __m128i e16__0_7 = _mm_slli_epi16(_mm_subs_epi16(v16__0_7, _mm_set1_epi16(128)), 4);
168  __m128i r16__0_7 = _mm_min_epi16(_mm_set1_epi16(255), _mm_max_epi16(zero, ((_mm_add_epi16(_mm_mulhi_epi16(c16__0_7, n298), _mm_mulhi_epi16(e16__0_7, n409)))))); // (298 * c + 409 * e + 128) ; //
169  __m128i g16__0_7 = _mm_min_epi16(_mm_set1_epi16(255), _mm_max_epi16(zero, ((_mm_sub_epi16(_mm_sub_epi16(_mm_mulhi_epi16(c16__0_7, n298), _mm_mulhi_epi16(d16__0_7, n100)), _mm_mulhi_epi16(e16__0_7, n208)))))); // (298 * c - 100 * d - 208 * e + 128)
170  __m128i b16__0_7 = _mm_min_epi16(_mm_set1_epi16(255), _mm_max_epi16(zero, ((_mm_add_epi16(_mm_mulhi_epi16(c16__0_7, n298), _mm_mulhi_epi16(d16__0_7, n516)))))); // clampbyte((298 * c + 516 * d + 128) >> 8);
171 
172  // Compute R, G, B values for second 8 pixels
173  __m128i c16__8_F = _mm_slli_epi16(_mm_subs_epi16(y16__8_F, _mm_set1_epi16(16)), 4);
174  __m128i d16__8_F = _mm_slli_epi16(_mm_subs_epi16(u16__8_F, _mm_set1_epi16(128)), 4); // perhaps could have done these u,v to d,e before the duplication
175  __m128i e16__8_F = _mm_slli_epi16(_mm_subs_epi16(v16__8_F, _mm_set1_epi16(128)), 4);
176  __m128i r16__8_F = _mm_min_epi16(_mm_set1_epi16(255), _mm_max_epi16(zero, ((_mm_add_epi16(_mm_mulhi_epi16(c16__8_F, n298), _mm_mulhi_epi16(e16__8_F, n409)))))); // (298 * c + 409 * e + 128) ; //
177  __m128i g16__8_F = _mm_min_epi16(_mm_set1_epi16(255), _mm_max_epi16(zero, ((_mm_sub_epi16(_mm_sub_epi16(_mm_mulhi_epi16(c16__8_F, n298), _mm_mulhi_epi16(d16__8_F, n100)), _mm_mulhi_epi16(e16__8_F, n208)))))); // (298 * c - 100 * d - 208 * e + 128)
178  __m128i b16__8_F = _mm_min_epi16(_mm_set1_epi16(255), _mm_max_epi16(zero, ((_mm_add_epi16(_mm_mulhi_epi16(c16__8_F, n298), _mm_mulhi_epi16(d16__8_F, n516)))))); // clampbyte((298 * c + 516 * d + 128) >> 8);
179 
180  if (FORMAT == RS_FORMAT_RGB8 || FORMAT == RS_FORMAT_RGBA8)
181  {
182  // Shuffle separate R, G, B values into four registers storing four pixels each in (R, G, B, A) order
183  __m128i rg8__0_7 = _mm_unpacklo_epi8(_mm_shuffle_epi8(r16__0_7, evens_odds), _mm_shuffle_epi8(g16__0_7, evens_odds)); // hi to take the odds which are the upper bytes we care about
184  __m128i ba8__0_7 = _mm_unpacklo_epi8(_mm_shuffle_epi8(b16__0_7, evens_odds), _mm_set1_epi8(-1));
185  __m128i rgba_0_3 = _mm_unpacklo_epi16(rg8__0_7, ba8__0_7);
186  __m128i rgba_4_7 = _mm_unpackhi_epi16(rg8__0_7, ba8__0_7);
187 
188  __m128i rg8__8_F = _mm_unpacklo_epi8(_mm_shuffle_epi8(r16__8_F, evens_odds), _mm_shuffle_epi8(g16__8_F, evens_odds)); // hi to take the odds which are the upper bytes we care about
189  __m128i ba8__8_F = _mm_unpacklo_epi8(_mm_shuffle_epi8(b16__8_F, evens_odds), _mm_set1_epi8(-1));
190  __m128i rgba_8_B = _mm_unpacklo_epi16(rg8__8_F, ba8__8_F);
191  __m128i rgba_C_F = _mm_unpackhi_epi16(rg8__8_F, ba8__8_F);
192 
193  if(FORMAT == RS_FORMAT_RGBA8)
194  {
195  // Store 16 pixels (64 bytes) at once
196  _mm_storeu_si128(dst++, rgba_0_3);
197  _mm_storeu_si128(dst++, rgba_4_7);
198  _mm_storeu_si128(dst++, rgba_8_B);
199  _mm_storeu_si128(dst++, rgba_C_F);
200  }
201 
202  if(FORMAT == RS_FORMAT_RGB8)
203  {
204  // Shuffle rgb triples to the start and end of each register
205  __m128i rgb0 = _mm_shuffle_epi8(rgba_0_3, _mm_setr_epi8( 3, 7, 11, 15, 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14));
206  __m128i rgb1 = _mm_shuffle_epi8(rgba_4_7, _mm_setr_epi8(0, 1, 2, 4, 3, 7, 11, 15, 5, 6, 8, 9, 10, 12, 13, 14));
207  __m128i rgb2 = _mm_shuffle_epi8(rgba_8_B, _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 3, 7, 11, 15, 10, 12, 13, 14));
208  __m128i rgb3 = _mm_shuffle_epi8(rgba_C_F, _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 3, 7, 11, 15 ));
209 
210  // Align registers and store 16 pixels (48 bytes) at once
211  _mm_storeu_si128(dst++, _mm_alignr_epi8(rgb1, rgb0, 4));
212  _mm_storeu_si128(dst++, _mm_alignr_epi8(rgb2, rgb1, 8));
213  _mm_storeu_si128(dst++, _mm_alignr_epi8(rgb3, rgb2, 12));
214  }
215  }
216 
217  if (FORMAT == RS_FORMAT_BGR8 || FORMAT == RS_FORMAT_BGRA8)
218  {
219  // Shuffle separate R, G, B values into four registers storing four pixels each in (B, G, R, A) order
220  __m128i bg8__0_7 = _mm_unpacklo_epi8(_mm_shuffle_epi8(b16__0_7, evens_odds), _mm_shuffle_epi8(g16__0_7, evens_odds)); // hi to take the odds which are the upper bytes we care about
221  __m128i ra8__0_7 = _mm_unpacklo_epi8(_mm_shuffle_epi8(r16__0_7, evens_odds), _mm_set1_epi8(-1));
222  __m128i bgra_0_3 = _mm_unpacklo_epi16(bg8__0_7, ra8__0_7);
223  __m128i bgra_4_7 = _mm_unpackhi_epi16(bg8__0_7, ra8__0_7);
224 
225  __m128i bg8__8_F = _mm_unpacklo_epi8(_mm_shuffle_epi8(b16__8_F, evens_odds), _mm_shuffle_epi8(g16__8_F, evens_odds)); // hi to take the odds which are the upper bytes we care about
226  __m128i ra8__8_F = _mm_unpacklo_epi8(_mm_shuffle_epi8(r16__8_F, evens_odds), _mm_set1_epi8(-1));
227  __m128i bgra_8_B = _mm_unpacklo_epi16(bg8__8_F, ra8__8_F);
228  __m128i bgra_C_F = _mm_unpackhi_epi16(bg8__8_F, ra8__8_F);
229 
230  if(FORMAT == RS_FORMAT_BGRA8)
231  {
232  // Store 16 pixels (64 bytes) at once
233  _mm_storeu_si128(dst++, bgra_0_3);
234  _mm_storeu_si128(dst++, bgra_4_7);
235  _mm_storeu_si128(dst++, bgra_8_B);
236  _mm_storeu_si128(dst++, bgra_C_F);
237  }
238 
239  if(FORMAT == RS_FORMAT_BGR8)
240  {
241  // Shuffle rgb triples to the start and end of each register
242  __m128i bgr0 = _mm_shuffle_epi8(bgra_0_3, _mm_setr_epi8( 3, 7, 11, 15, 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14));
243  __m128i bgr1 = _mm_shuffle_epi8(bgra_4_7, _mm_setr_epi8(0, 1, 2, 4, 3, 7, 11, 15, 5, 6, 8, 9, 10, 12, 13, 14));
244  __m128i bgr2 = _mm_shuffle_epi8(bgra_8_B, _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 3, 7, 11, 15, 10, 12, 13, 14));
245  __m128i bgr3 = _mm_shuffle_epi8(bgra_C_F, _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 3, 7, 11, 15 ));
246 
247  // Align registers and store 16 pixels (48 bytes) at once
248  _mm_storeu_si128(dst++, _mm_alignr_epi8(bgr1, bgr0, 4));
249  _mm_storeu_si128(dst++, _mm_alignr_epi8(bgr2, bgr1, 8));
250  _mm_storeu_si128(dst++, _mm_alignr_epi8(bgr3, bgr2, 12));
251  }
252  }
253  }
254 #else // Generic code for when SSSE3 is not available.
255  auto src = reinterpret_cast<const uint8_t *>(s);
256  auto dst = reinterpret_cast<uint8_t *>(d[0]);
257  for(; n; n -= 16, src += 32)
258  {
259  if(FORMAT == RS_FORMAT_Y8)
260  {
261  uint8_t out[16] = {
262  src[ 0], src[ 2], src[ 4], src[ 6],
263  src[ 8], src[10], src[12], src[14],
264  src[16], src[18], src[20], src[22],
265  src[24], src[26], src[28], src[30],
266  };
267  memcpy(dst, out, sizeof out);
268  dst += sizeof out;
269  continue;
270  }
271 
272  if(FORMAT == RS_FORMAT_Y16)
273  {
274  // Y16 is little-endian. We output Y << 8.
275  uint8_t out[32] = {
276  0, src[ 0], 0, src[ 2], 0, src[ 4], 0, src[ 6],
277  0, src[ 8], 0, src[10], 0, src[12], 0, src[14],
278  0, src[16], 0, src[18], 0, src[20], 0, src[22],
279  0, src[24], 0, src[26], 0, src[28], 0, src[30],
280  };
281  memcpy(dst, out, sizeof out);
282  dst += sizeof out;
283  continue;
284  }
285 
286  int16_t y[16] = {
287  src[ 0], src[ 2], src[ 4], src[ 6],
288  src[ 8], src[10], src[12], src[14],
289  src[16], src[18], src[20], src[22],
290  src[24], src[26], src[28], src[30],
291  }, u[16] = {
292  src[ 1], src[ 1], src[ 5], src[ 5],
293  src[ 9], src[ 9], src[13], src[13],
294  src[17], src[17], src[21], src[21],
295  src[25], src[25], src[29], src[29],
296  }, v[16] = {
297  src[ 3], src[ 3], src[ 7], src[ 7],
298  src[11], src[11], src[15], src[15],
299  src[19], src[19], src[23], src[23],
300  src[27], src[27], src[31], src[31],
301  };
302 
303  uint8_t r[16], g[16], b[16];
304  for(int i = 0; i < 16; i++)
305  {
306  int32_t c = y[i] - 16;
307  int32_t d = u[i] - 128;
308  int32_t e = v[i] - 128;
309 
310  int32_t t;
311  #define clamp(x) ((t=(x)) > 255 ? 255 : t < 0 ? 0 : t)
312  r[i] = clamp((298 * c + 409 * e + 128) >> 8);
313  g[i] = clamp((298 * c - 100 * d - 409 * e + 128) >> 8);
314  b[i] = clamp((298 * c + 516 * d + 128) >> 8);
315  #undef clamp
316  }
317 
318  if(FORMAT == RS_FORMAT_RGB8)
319  {
320  uint8_t out[16*3] = {
321  r[ 0], g[ 0], b[ 0], r[ 1], g[ 1], b[ 1],
322  r[ 2], g[ 2], b[ 2], r[ 3], g[ 3], b[ 3],
323  r[ 4], g[ 4], b[ 4], r[ 5], g[ 5], b[ 5],
324  r[ 6], g[ 6], b[ 6], r[ 7], g[ 7], b[ 7],
325  r[ 8], g[ 8], b[ 8], r[ 9], g[ 9], b[ 9],
326  r[10], g[10], b[10], r[11], g[11], b[11],
327  r[12], g[12], b[12], r[13], g[13], b[13],
328  r[14], g[14], b[14], r[15], g[15], b[15],
329  };
330  memcpy(dst, out, sizeof out);
331  dst += sizeof out;
332  continue;
333  }
334 
335  if(FORMAT == RS_FORMAT_BGR8)
336  {
337  uint8_t out[16*3] = {
338  b[ 0], g[ 0], r[ 0], b[ 1], g[ 1], r[ 1],
339  b[ 2], g[ 2], r[ 2], b[ 3], g[ 3], r[ 3],
340  b[ 4], g[ 4], r[ 4], b[ 5], g[ 5], r[ 5],
341  b[ 6], g[ 6], r[ 6], b[ 7], g[ 7], r[ 7],
342  b[ 8], g[ 8], r[ 8], b[ 9], g[ 9], r[ 9],
343  b[10], g[10], r[10], b[11], g[11], r[11],
344  b[12], g[12], r[12], b[13], g[13], r[13],
345  b[14], g[14], r[14], b[15], g[15], r[15],
346  };
347  memcpy(dst, out, sizeof out);
348  dst += sizeof out;
349  continue;
350  }
351 
352  if(FORMAT == RS_FORMAT_RGBA8)
353  {
354  uint8_t out[16*4] = {
355  r[ 0], g[ 0], b[ 0], 255, r[ 1], g[ 1], b[ 1], 255,
356  r[ 2], g[ 2], b[ 2], 255, r[ 3], g[ 3], b[ 3], 255,
357  r[ 4], g[ 4], b[ 4], 255, r[ 5], g[ 5], b[ 5], 255,
358  r[ 6], g[ 6], b[ 6], 255, r[ 7], g[ 7], b[ 7], 255,
359  r[ 8], g[ 8], b[ 8], 255, r[ 9], g[ 9], b[ 9], 255,
360  r[10], g[10], b[10], 255, r[11], g[11], b[11], 255,
361  r[12], g[12], b[12], 255, r[13], g[13], b[13], 255,
362  r[14], g[14], b[14], 255, r[15], g[15], b[15], 255,
363  };
364  memcpy(dst, out, sizeof out);
365  dst += sizeof out;
366  continue;
367  }
368 
369  if(FORMAT == RS_FORMAT_BGRA8)
370  {
371  uint8_t out[16*4] = {
372  b[ 0], g[ 0], r[ 0], 255, b[ 1], g[ 1], r[ 1], 255,
373  b[ 2], g[ 2], r[ 2], 255, b[ 3], g[ 3], r[ 3], 255,
374  b[ 4], g[ 4], r[ 4], 255, b[ 5], g[ 5], r[ 5], 255,
375  b[ 6], g[ 6], r[ 6], 255, b[ 7], g[ 7], r[ 7], 255,
376  b[ 8], g[ 8], r[ 8], 255, b[ 9], g[ 9], r[ 9], 255,
377  b[10], g[10], r[10], 255, b[11], g[11], r[11], 255,
378  b[12], g[12], r[12], 255, b[13], g[13], r[13], 255,
379  b[14], g[14], r[14], 255, b[15], g[15], r[15], 255,
380  };
381  memcpy(dst, out, sizeof out);
382  dst += sizeof out;
383  continue;
384  }
385  }
386 #endif
387  }
388 
390  // 2-in-1 format splitting routines //
392 
393  template<class SOURCE, class SPLIT_A, class SPLIT_B> void split_frame(byte * const dest[], int count, const SOURCE * source, SPLIT_A split_a, SPLIT_B split_b)
394  {
395  auto a = reinterpret_cast<decltype(split_a(SOURCE())) *>(dest[0]);
396  auto b = reinterpret_cast<decltype(split_b(SOURCE())) *>(dest[1]);
397  for(int i=0; i<count; ++i)
398  {
399  *a++ = split_a(*source);
400  *b++ = split_b(*source++);
401  }
402  }
403 
404  struct y8i_pixel { uint8_t l, r; };
405  void unpack_y8_y8_from_y8i(byte * const dest[], const byte * source, int count)
406  {
407  split_frame(dest, count, reinterpret_cast<const y8i_pixel *>(source),
408  [](const y8i_pixel & p) -> uint8_t { return p.l; },
409  [](const y8i_pixel & p) -> uint8_t { return p.r; });
410  }
411 
412  struct y12i_pixel { uint8_t rl : 8, rh : 4, ll : 4, lh : 8; int l() const { return lh << 4 | ll; } int r() const { return rh << 8 | rl; } };
413  void unpack_y16_y16_from_y12i_10(byte * const dest[], const byte * source, int count)
414  {
415  split_frame(dest, count, reinterpret_cast<const y12i_pixel *>(source),
416  [](const y12i_pixel & p) -> uint16_t { return p.l() << 6 | p.l() >> 4; }, // We want to convert 10-bit data to 16-bit data
417  [](const y12i_pixel & p) -> uint16_t { return p.r() << 6 | p.r() >> 4; }); // Multiply by 64 1/16 to efficiently approximate 65535/1023
418  }
419 
420  struct f200_inzi_pixel { uint16_t z16; uint8_t y8; };
421  void unpack_z16_y8_from_f200_inzi(byte * const dest[], const byte * source, int count)
422  {
423  split_frame(dest, count, reinterpret_cast<const f200_inzi_pixel *>(source),
424  [](const f200_inzi_pixel & p) -> uint16_t { return p.z16; },
425  [](const f200_inzi_pixel & p) -> uint8_t { return p.y8; });
426  }
427 
428  void unpack_z16_y16_from_f200_inzi(byte * const dest[], const byte * source, int count)
429  {
430  split_frame(dest, count, reinterpret_cast<const f200_inzi_pixel *>(source),
431  [](const f200_inzi_pixel & p) -> uint16_t { return p.z16; },
432  [](const f200_inzi_pixel & p) -> uint16_t { return p.y8 | p.y8 << 8; });
433  }
434 
435  void unpack_z16_y8_from_sr300_inzi(byte * const dest[], const byte * source, int count)
436  {
437  auto in = reinterpret_cast<const uint16_t *>(source);
438  auto out_ir = reinterpret_cast<uint8_t *>(dest[1]);
439  for(int i=0; i<count; ++i) *out_ir++ = *in++ >> 2;
440  memcpy(dest[0], in, count*2);
441  }
442 
443  void unpack_z16_y16_from_sr300_inzi (byte * const dest[], const byte * source, int count)
444  {
445  auto in = reinterpret_cast<const uint16_t *>(source);
446  auto out_ir = reinterpret_cast<uint16_t *>(dest[1]);
447  for(int i=0; i<count; ++i) *out_ir++ = *in++ << 6;
448  memcpy(dest[0], in, count*2);
449  }
450 
451 #pragma GCC diagnostic push
452 #pragma GCC diagnostic ignored "-Wmultichar"
453 #ifdef __APPLE
454 #pragma GCC diagnostic ignored "-Wfour-char-constants"
455 #endif
456  // Native pixel formats //
459  const native_pixel_format pf_raw8 = { 'RAW8', 1, 1,{ { false, &copy_pixels<1>, { { RS_STREAM_FISHEYE, RS_FORMAT_RAW8 } } } } };
460  const native_pixel_format pf_rw16 = { 'RW16', 1, 2,{ { false, &copy_pixels<2>, { { RS_STREAM_COLOR, RS_FORMAT_RAW16 } } } } };
461  const native_pixel_format pf_rw10 = { 'pRAA', 1, 1,{ { false, &copy_raw10, { { RS_STREAM_COLOR, RS_FORMAT_RAW10 } } } } };
462  const native_pixel_format pf_yuy2 = { 'YUY2', 1, 2,{ { true, &unpack_yuy2<RS_FORMAT_RGB8 >, { { RS_STREAM_COLOR, RS_FORMAT_RGB8 } } },
463  { false, &copy_pixels<2>, { { RS_STREAM_COLOR, RS_FORMAT_YUYV } } },
464  { true, &unpack_yuy2<RS_FORMAT_RGBA8>, { { RS_STREAM_COLOR, RS_FORMAT_RGBA8 } } },
465  { true, &unpack_yuy2<RS_FORMAT_BGR8 >, { { RS_STREAM_COLOR, RS_FORMAT_BGR8 } } },
466  { true, &unpack_yuy2<RS_FORMAT_BGRA8>, { { RS_STREAM_COLOR, RS_FORMAT_BGRA8 } } } } };
467  const native_pixel_format pf_y8 = { 'GREY', 1, 1,{ { false, &copy_pixels<1>, { { RS_STREAM_INFRARED, RS_FORMAT_Y8 } } } } };
468  const native_pixel_format pf_y16 = { 'Y16 ', 1, 2,{ { true, &unpack_y16_from_y16_10, { { RS_STREAM_INFRARED, RS_FORMAT_Y16 } } } } };
469  const native_pixel_format pf_y8i = { 'Y8I ', 1, 2,{ { true, &unpack_y8_y8_from_y8i, { { RS_STREAM_INFRARED, RS_FORMAT_Y8 },{ RS_STREAM_INFRARED2, RS_FORMAT_Y8 } } } } };
470  const native_pixel_format pf_y12i = { 'Y12I', 1, 3,{ { true, &unpack_y16_y16_from_y12i_10, { { RS_STREAM_INFRARED, RS_FORMAT_Y16 },{ RS_STREAM_INFRARED2, RS_FORMAT_Y16 } } } } };
471  const native_pixel_format pf_z16 = { 'Z16 ', 1, 2,{ { false, &copy_pixels<2>, { { RS_STREAM_DEPTH, RS_FORMAT_Z16 } } },
472  { false, &copy_pixels<2>, { { RS_STREAM_DEPTH, RS_FORMAT_DISPARITY16 } } } } };
473  const native_pixel_format pf_invz = { 'Z16 ', 1, 2, { { false, &copy_pixels<2>, { { RS_STREAM_DEPTH, RS_FORMAT_Z16 } } } } };
474  const native_pixel_format pf_f200_invi = { 'Y10 ', 1, 1, { { false, &copy_pixels<1>, { { RS_STREAM_INFRARED, RS_FORMAT_Y8 } } },
475  { true, &unpack_y16_from_y8, { { RS_STREAM_INFRARED, RS_FORMAT_Y16 } } } } };
476  const native_pixel_format pf_f200_inzi = { 'INZI', 1, 3,{ { true, &unpack_z16_y8_from_f200_inzi, { { RS_STREAM_DEPTH, RS_FORMAT_Z16 },{ RS_STREAM_INFRARED, RS_FORMAT_Y8 } } },
477  { true, &unpack_z16_y16_from_f200_inzi, { { RS_STREAM_DEPTH, RS_FORMAT_Z16 },{ RS_STREAM_INFRARED, RS_FORMAT_Y16 } } } } };
478  const native_pixel_format pf_sr300_invi = { 'Y10 ', 1, 2,{ { true, &unpack_y8_from_y16_10, { { RS_STREAM_INFRARED, RS_FORMAT_Y8 } } },
479  { true, &unpack_y16_from_y16_10, { { RS_STREAM_INFRARED, RS_FORMAT_Y16 } } } } };
480  const native_pixel_format pf_sr300_inzi = { 'INZI', 2, 2,{ { true, &unpack_z16_y8_from_sr300_inzi, { { RS_STREAM_DEPTH, RS_FORMAT_Z16 },{ RS_STREAM_INFRARED, RS_FORMAT_Y8 } } },
481  { true, &unpack_z16_y16_from_sr300_inzi, { { RS_STREAM_DEPTH, RS_FORMAT_Z16 },{ RS_STREAM_INFRARED, RS_FORMAT_Y16 } } } } };
482 #pragma GCC diagnostic pop
483 
485  // Deprojection //
487 
488  template<class MAP_DEPTH> void deproject_depth(float * points, const rs_intrinsics & intrin, const uint16_t * depth, MAP_DEPTH map_depth)
489  {
490  for(int y=0; y<intrin.height; ++y)
491  {
492  for(int x=0; x<intrin.width; ++x)
493  {
494  const float pixel[] = { (float) x, (float) y};
495  rs_deproject_pixel_to_point(points, &intrin, pixel, map_depth(*depth++));
496  points += 3;
497  }
498  }
499  }
500 
501  void deproject_z(float * points, const rs_intrinsics & z_intrin, const uint16_t * z_pixels, float z_scale)
502  {
503  deproject_depth(points, z_intrin, z_pixels, [z_scale](uint16_t z) { return z_scale * z; });
504  }
505 
506  void deproject_disparity(float * points, const rs_intrinsics & disparity_intrin, const uint16_t * disparity_pixels, float disparity_scale)
507  {
508  deproject_depth(points, disparity_intrin, disparity_pixels, [disparity_scale](uint16_t disparity) { return disparity_scale / disparity; });
509  }
510 
512  // Image alignment //
514 
515  template<class GET_DEPTH, class TRANSFER_PIXEL> void align_images(const rs_intrinsics & depth_intrin, const rs_extrinsics & depth_to_other, const rs_intrinsics & other_intrin, GET_DEPTH get_depth, TRANSFER_PIXEL transfer_pixel)
516  {
517  // Iterate over the pixels of the depth image
518 #pragma omp parallel for schedule(dynamic)
519  for(int depth_y = 0; depth_y < depth_intrin.height; ++depth_y)
520  {
521  int depth_pixel_index = depth_y * depth_intrin.width;
522  for(int depth_x = 0; depth_x < depth_intrin.width; ++depth_x, ++depth_pixel_index)
523  {
524  // Skip over depth pixels with the value of zero, we have no depth data so we will not write anything into our aligned images
525  if(float depth = get_depth(depth_pixel_index))
526  {
527  // Map the top-left corner of the depth pixel onto the other image
528  float depth_pixel[2] = {depth_x-0.5f, depth_y-0.5f}, depth_point[3], other_point[3], other_pixel[2];
529  rs_deproject_pixel_to_point(depth_point, &depth_intrin, depth_pixel, depth);
530  rs_transform_point_to_point(other_point, &depth_to_other, depth_point);
531  rs_project_point_to_pixel(other_pixel, &other_intrin, other_point);
532  const int other_x0 = static_cast<int>(other_pixel[0] + 0.5f);
533  const int other_y0 = static_cast<int>(other_pixel[1] + 0.5f);
534 
535  // Map the bottom-right corner of the depth pixel onto the other image
536  depth_pixel[0] = depth_x+0.5f; depth_pixel[1] = depth_y+0.5f;
537  rs_deproject_pixel_to_point(depth_point, &depth_intrin, depth_pixel, depth);
538  rs_transform_point_to_point(other_point, &depth_to_other, depth_point);
539  rs_project_point_to_pixel(other_pixel, &other_intrin, other_point);
540  const int other_x1 = static_cast<int>(other_pixel[0] + 0.5f);
541  const int other_y1 = static_cast<int>(other_pixel[1] + 0.5f);
542 
543  if(other_x0 < 0 || other_y0 < 0 || other_x1 >= other_intrin.width || other_y1 >= other_intrin.height) continue;
544 
545  // Transfer between the depth pixels and the pixels inside the rectangle on the other image
546  for(int y=other_y0; y<=other_y1; ++y) for(int x=other_x0; x<=other_x1; ++x) transfer_pixel(depth_pixel_index, y * other_intrin.width + x);
547  }
548  }
549  }
550  }
551 
552  void align_z_to_other(byte * z_aligned_to_other, const uint16_t * z_pixels, float z_scale, const rs_intrinsics & z_intrin, const rs_extrinsics & z_to_other, const rs_intrinsics & other_intrin)
553  {
554  auto out_z = (uint16_t *)(z_aligned_to_other);
555  align_images(z_intrin, z_to_other, other_intrin,
556  [z_pixels, z_scale](int z_pixel_index) { return z_scale * z_pixels[z_pixel_index]; },
557  [out_z, z_pixels](int z_pixel_index, int other_pixel_index) { out_z[other_pixel_index] = out_z[other_pixel_index] ? std::min(out_z[other_pixel_index],z_pixels[z_pixel_index]) : z_pixels[z_pixel_index]; });
558  }
559 
560  void align_disparity_to_other(byte * disparity_aligned_to_other, const uint16_t * disparity_pixels, float disparity_scale, const rs_intrinsics & disparity_intrin, const rs_extrinsics & disparity_to_other, const rs_intrinsics & other_intrin)
561  {
562  auto out_disparity = (uint16_t *)(disparity_aligned_to_other);
563  align_images(disparity_intrin, disparity_to_other, other_intrin,
564  [disparity_pixels, disparity_scale](int disparity_pixel_index) { return disparity_scale / disparity_pixels[disparity_pixel_index]; },
565  [out_disparity, disparity_pixels](int disparity_pixel_index, int other_pixel_index) { out_disparity[other_pixel_index] = disparity_pixels[disparity_pixel_index]; });
566  }
567 
568  template<int N> struct bytes { char b[N]; };
569  template<int N, class GET_DEPTH> void align_other_to_depth_bytes(byte * other_aligned_to_depth, GET_DEPTH get_depth, const rs_intrinsics & depth_intrin, const rs_extrinsics & depth_to_other, const rs_intrinsics & other_intrin, const byte * other_pixels)
570  {
571  auto in_other = (const bytes<N> *)(other_pixels);
572  auto out_other = (bytes<N> *)(other_aligned_to_depth);
573  align_images(depth_intrin, depth_to_other, other_intrin, get_depth,
574  [out_other, in_other](int depth_pixel_index, int other_pixel_index) { out_other[depth_pixel_index] = in_other[other_pixel_index]; });
575  }
576 
577  template<class GET_DEPTH> void align_other_to_depth(byte * other_aligned_to_depth, GET_DEPTH get_depth, const rs_intrinsics & depth_intrin, const rs_extrinsics & depth_to_other, const rs_intrinsics & other_intrin, const byte * other_pixels, rs_format other_format)
578  {
579  switch(other_format)
580  {
581  case RS_FORMAT_Y8:
582  align_other_to_depth_bytes<1>(other_aligned_to_depth, get_depth, depth_intrin, depth_to_other, other_intrin, other_pixels); break;
583  case RS_FORMAT_Y16: case RS_FORMAT_Z16:
584  align_other_to_depth_bytes<2>(other_aligned_to_depth, get_depth, depth_intrin, depth_to_other, other_intrin, other_pixels); break;
585  case RS_FORMAT_RGB8: case RS_FORMAT_BGR8:
586  align_other_to_depth_bytes<3>(other_aligned_to_depth, get_depth, depth_intrin, depth_to_other, other_intrin, other_pixels); break;
587  case RS_FORMAT_RGBA8: case RS_FORMAT_BGRA8:
588  align_other_to_depth_bytes<4>(other_aligned_to_depth, get_depth, depth_intrin, depth_to_other, other_intrin, other_pixels); break;
589  default:
590  assert(false); // NOTE: rs_align_other_to_depth_bytes<2>(...) is not appropriate for RS_FORMAT_YUYV/RS_FORMAT_RAW10 images, no logic prevents U/V channels from being written to one another
591  }
592  }
593 
594  void align_other_to_z(byte * other_aligned_to_z, const uint16_t * z_pixels, float z_scale, const rs_intrinsics & z_intrin, const rs_extrinsics & z_to_other, const rs_intrinsics & other_intrin, const byte * other_pixels, rs_format other_format)
595  {
596  align_other_to_depth(other_aligned_to_z, [z_pixels, z_scale](int z_pixel_index) { return z_scale * z_pixels[z_pixel_index]; }, z_intrin, z_to_other, other_intrin, other_pixels, other_format);
597  }
598 
599  void align_other_to_disparity(byte * other_aligned_to_disparity, const uint16_t * disparity_pixels, float disparity_scale, const rs_intrinsics & disparity_intrin, const rs_extrinsics & disparity_to_other, const rs_intrinsics & other_intrin, const byte * other_pixels, rs_format other_format)
600  {
601  align_other_to_depth(other_aligned_to_disparity, [disparity_pixels, disparity_scale](int disparity_pixel_index) { return disparity_scale / disparity_pixels[disparity_pixel_index]; }, disparity_intrin, disparity_to_other, other_intrin, other_pixels, other_format);
602  }
603 
605  // Image rectification //
607 
608  std::vector<int> compute_rectification_table(const rs_intrinsics & rect_intrin, const rs_extrinsics & rect_to_unrect, const rs_intrinsics & unrect_intrin)
609  {
610  std::vector<int> rectification_table;
611  rectification_table.resize(rect_intrin.width * rect_intrin.height);
612  align_images(rect_intrin, rect_to_unrect, unrect_intrin, [](int) { return 1.0f; },
613  [&rectification_table](int rect_pixel_index, int unrect_pixel_index) { rectification_table[rect_pixel_index] = unrect_pixel_index; });
614  return rectification_table;
615  }
616 
617  template<class T> void rectify_image_pixels(T * rect_pixels, const std::vector<int> & rectification_table, const T * unrect_pixels)
618  {
619  for(auto entry : rectification_table) *rect_pixels++ = unrect_pixels[entry];
620  }
621 
622  void rectify_image(uint8_t * rect_pixels, const std::vector<int> & rectification_table, const uint8_t * unrect_pixels, rs_format format)
623  {
624  switch(format)
625  {
626  case RS_FORMAT_Y8:
627  return rectify_image_pixels((bytes<1> *)rect_pixels, rectification_table, (const bytes<1> *)unrect_pixels);
628  case RS_FORMAT_Y16: case RS_FORMAT_Z16:
629  return rectify_image_pixels((bytes<2> *)rect_pixels, rectification_table, (const bytes<2> *)unrect_pixels);
630  case RS_FORMAT_RGB8: case RS_FORMAT_BGR8:
631  return rectify_image_pixels((bytes<3> *)rect_pixels, rectification_table, (const bytes<3> *)unrect_pixels);
632  case RS_FORMAT_RGBA8: case RS_FORMAT_BGRA8:
633  return rectify_image_pixels((bytes<4> *)rect_pixels, rectification_table, (const bytes<4> *)unrect_pixels);
634  default:
635  assert(false); // NOTE: rectify_image_pixels(...) is not appropriate for RS_FORMAT_YUYV images, no logic prevents U/V channels from being written to one another
636  }
637  }
638 }
639 
640 #pragma pack(pop)
void align_other_to_z(byte *other_aligned_to_z, const uint16_t *z_pixels, float z_scale, const rs_intrinsics &z_intrin, const rs_extrinsics &z_to_other, const rs_intrinsics &other_intrin, const byte *other_pixels, rs_format other_format)
Definition: image.cpp:594
GLboolean GLboolean g
Definition: glext.h:1104
void unpack_y16_from_y8(byte *const d[], const byte *s, int n)
Definition: image.cpp:69
#define clamp(x)
const native_pixel_format pf_sr300_invi
Definition: image.cpp:478
void unpack_z16_y8_from_f200_inzi(byte *const dest[], const byte *source, int count)
Definition: image.cpp:421
const native_pixel_format pf_rw10
Definition: image.cpp:461
void rectify_image_pixels(T *rect_pixels, const std::vector< int > &rectification_table, const T *unrect_pixels)
Definition: image.cpp:617
rs_error * e
GLint GLint GLsizei GLsizei height
Definition: glext.h:112
void unpack_y8_y8_from_y8i(byte *const dest[], const byte *source, int count)
Definition: image.cpp:405
GLint GLint GLint GLint GLint GLint y
Definition: glext.h:114
GLdouble GLdouble z
Definition: glext.h:404
const native_pixel_format pf_y8i
Definition: image.cpp:469
void align_disparity_to_other(byte *disparity_aligned_to_other, const uint16_t *disparity_pixels, float disparity_scale, const rs_intrinsics &disparity_intrin, const rs_extrinsics &disparity_to_other, const rs_intrinsics &other_intrin)
Definition: image.cpp:560
const native_pixel_format pf_y12i
Definition: image.cpp:470
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: glext.h:8966
Definition: archive.h:12
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glext.h:112
int get_image_bpp(rs_format format)
Definition: image.cpp:29
int r() const
Definition: image.cpp:412
void unpack_z16_y8_from_sr300_inzi(byte *const dest[], const byte *source, int count)
Definition: image.cpp:435
GLenum src
Definition: glext.h:1735
GLdouble n
Definition: glext.h:1950
static void rs_project_point_to_pixel(float pixel[2], const struct rs_intrinsics *intrin, const float point[3])
Definition: rsutil.h:11
static void rs_transform_point_to_point(float to_point[3], const struct rs_extrinsics *extrin, const float from_point[3])
Definition: rsutil.h:55
const native_pixel_format pf_y16
Definition: image.cpp:468
void split_frame(byte *const dest[], int count, const SOURCE *source, SPLIT_A split_a, SPLIT_B split_b)
Definition: image.cpp:393
void deproject_disparity(float *points, const rs_intrinsics &disparity_intrin, const uint16_t *disparity_pixels, float disparity_scale)
Definition: image.cpp:506
GLenum GLenum dst
Definition: glext.h:1735
const native_pixel_format pf_y8
Definition: image.cpp:467
void align_images(const rs_intrinsics &depth_intrin, const rs_extrinsics &depth_to_other, const rs_intrinsics &other_intrin, GET_DEPTH get_depth, TRANSFER_PIXEL transfer_pixel)
Definition: image.cpp:515
const GLubyte * c
Definition: glext.h:11542
void copy_pixels(byte *const dest[], const byte *source, int count)
Definition: image.cpp:53
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
GLuint GLuint GLsizei count
Definition: glext.h:111
void unpack_z16_y16_from_sr300_inzi(byte *const dest[], const byte *source, int count)
Definition: image.cpp:443
const native_pixel_format pf_sr300_inzi
Definition: image.cpp:480
void unpack_y8_from_y16_10(byte *const d[], const byte *s, int n)
Definition: image.cpp:71
GLfixed y1
Definition: glext.h:4952
void deproject_z(float *points, const rs_intrinsics &z_intrin, const uint16_t *z_pixels, float z_scale)
Definition: image.cpp:501
void unpack_y16_from_y16_10(byte *const d[], const byte *s, int n)
Definition: image.cpp:70
static void rs_deproject_pixel_to_point(float point[3], const struct rs_intrinsics *intrin, const float pixel[2], float depth)
Definition: rsutil.h:33
rs_format
Formats: defines how each stream can be encoded.
Definition: rs.h:53
void unpack_pixels(byte *const dest[], int count, const SOURCE *source, UNPACK unpack)
Definition: image.cpp:63
void deproject_depth(float *points, const rs_intrinsics &intrin, const uint16_t *depth, MAP_DEPTH map_depth)
Definition: image.cpp:488
void unpack_z16_y16_from_f200_inzi(byte *const dest[], const byte *source, int count)
Definition: image.cpp:428
GLdouble GLdouble t
Definition: glext.h:239
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:1104
int height
Definition: rs.h:303
const GLdouble * v
Definition: glext.h:232
void align_other_to_depth_bytes(byte *other_aligned_to_depth, GET_DEPTH get_depth, const rs_intrinsics &depth_intrin, const rs_extrinsics &depth_to_other, const rs_intrinsics &other_intrin, const byte *other_pixels)
Definition: image.cpp:569
std::vector< int > compute_rectification_table(const rs_intrinsics &rect_intrin, const rs_extrinsics &rect_to_unrect, const rs_intrinsics &unrect_intrin)
Definition: image.cpp:608
const native_pixel_format pf_f200_inzi
Definition: image.cpp:476
int width
Definition: rs.h:302
const native_pixel_format pf_z16
Definition: image.cpp:471
Video stream intrinsics.
Definition: rs.h:300
GLboolean GLboolean GLboolean b
Definition: glext.h:1104
void unpack_rw10_from_rw8(byte *const d[], const byte *s, int n)
Definition: image.cpp:72
Cross-stream extrinsics: encode the topology describing how the different devices are connected...
Definition: rs.h:332
const native_pixel_format pf_rw16
Definition: image.cpp:460
void align_z_to_other(byte *z_aligned_to_other, const uint16_t *z_pixels, float z_scale, const rs_intrinsics &z_intrin, const rs_extrinsics &z_to_other, const rs_intrinsics &other_intrin)
Definition: image.cpp:552
void rectify_image(uint8_t *rect_pixels, const std::vector< int > &rectification_table, const uint8_t *unrect_pixels, rs_format format)
Definition: image.cpp:622
uint8_t byte
Definition: types.h:42
GLdouble s
Definition: glext.h:231
GLuint in
Definition: glext.h:8313
GLint GLint GLsizei width
Definition: glext.h:112
GLsizei GLsizei GLchar * source
Definition: glext.h:672
size_t get_image_size(int width, int height, rs_format format)
Definition: image.cpp:22
int l() const
Definition: image.cpp:412
GLuint GLfloat GLfloat y0
Definition: glext.h:8966
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glext.h:112
void unpack_yuy2(byte *const d[], const byte *s, int n)
Definition: image.cpp:109
const native_pixel_format pf_yuy2
Definition: image.cpp:462
void align_other_to_depth(byte *other_aligned_to_depth, GET_DEPTH get_depth, const rs_intrinsics &depth_intrin, const rs_extrinsics &depth_to_other, const rs_intrinsics &other_intrin, const byte *other_pixels, rs_format other_format)
Definition: image.cpp:577
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glext.h:8966
void align_other_to_disparity(byte *other_aligned_to_disparity, const uint16_t *disparity_pixels, float disparity_scale, const rs_intrinsics &disparity_intrin, const rs_extrinsics &disparity_to_other, const rs_intrinsics &other_intrin, const byte *other_pixels, rs_format other_format)
Definition: image.cpp:599
void copy_raw10(byte *const dest[], const byte *source, int count)
Definition: image.cpp:58
const native_pixel_format pf_f200_invi
Definition: image.cpp:474
GLfloat GLfloat p
Definition: glext.h:11539
GLdouble GLdouble GLdouble r
Definition: glext.h:247
const native_pixel_format pf_invz
Definition: image.cpp:473
GLint GLint GLint GLint GLint x
Definition: glext.h:114
const native_pixel_format pf_raw8
Definition: image.cpp:459
void unpack_y16_y16_from_y12i_10(byte *const dest[], const byte *source, int count)
Definition: image.cpp:413


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Fri Mar 13 2020 03:16:17