|
27 | 27 | #include "libfreenect.h"
|
28 | 28 | #include "freenect_internal.h"
|
29 | 29 | #include "registration.h"
|
| 30 | +#include "convert.h" |
30 | 31 | #include <stdlib.h>
|
31 | 32 | #include <string.h>
|
32 | 33 | #include <stdio.h>
|
@@ -73,65 +74,56 @@ static void freenect_init_depth_to_rgb(int32_t* depth_to_rgb, freenect_zero_plan
|
73 | 74 | }
|
74 | 75 | }
|
75 | 76 |
|
76 |
| -// unrolled inner loop of the 11-bit unpacker |
77 |
| -static inline void unpack_8_pixels(uint8_t *raw, uint16_t *frame) |
| 77 | +// apply registration data to a single frame |
| 78 | +FN_INTERNAL int freenect_apply_registration(const freenect_registration* reg, const freenect_frame_mode input_mode, void* input, uint16_t* output_mm) |
78 | 79 | {
|
79 |
| - uint16_t baseMask = 0x7FF; |
80 |
| - |
81 |
| - uint8_t r0 = *(raw+0); |
82 |
| - uint8_t r1 = *(raw+1); |
83 |
| - uint8_t r2 = *(raw+2); |
84 |
| - uint8_t r3 = *(raw+3); |
85 |
| - uint8_t r4 = *(raw+4); |
86 |
| - uint8_t r5 = *(raw+5); |
87 |
| - uint8_t r6 = *(raw+6); |
88 |
| - uint8_t r7 = *(raw+7); |
89 |
| - uint8_t r8 = *(raw+8); |
90 |
| - uint8_t r9 = *(raw+9); |
91 |
| - uint8_t r10 = *(raw+10); |
92 |
| - |
93 |
| - frame[0] = (r0<<3) | (r1>>5); |
94 |
| - frame[1] = ((r1<<6) | (r2>>2) ) & baseMask; |
95 |
| - frame[2] = ((r2<<9) | (r3<<1) | (r4>>7) ) & baseMask; |
96 |
| - frame[3] = ((r4<<4) | (r5>>4) ) & baseMask; |
97 |
| - frame[4] = ((r5<<7) | (r6>>1) ) & baseMask; |
98 |
| - frame[5] = ((r6<<10) | (r7<<2) | (r8>>6) ) & baseMask; |
99 |
| - frame[6] = ((r8<<5) | (r9>>3) ) & baseMask; |
100 |
| - frame[7] = ((r9<<8) | (r10) ) & baseMask; |
101 |
| -} |
| 80 | + if (!reg || !input || !output_mm) return -1; |
| 81 | + if (!input_mode.is_valid) return -1; |
| 82 | + if (input_mode.resolution != FREENECT_RESOLUTION_MEDIUM) return -2; |
| 83 | + |
| 84 | + if (input_mode.depth_format == FREENECT_DEPTH_REGISTERED) { |
| 85 | + memcpy(output_mm, input, input_mode.bytes); |
| 86 | + return 0; |
| 87 | + } |
102 | 88 |
|
103 |
| -// apply registration data to a single packed frame |
104 |
| -FN_INTERNAL int freenect_apply_registration(freenect_device* dev, uint8_t* input, uint16_t* output_mm, bool unpacked) |
105 |
| -{ |
106 |
| - freenect_registration* reg = &(dev->registration); |
107 | 89 | // set output buffer to zero using pointer-sized memory access (~ 30-40% faster than memset)
|
108 | 90 | size_t i, *wipe = (size_t*)output_mm;
|
109 | 91 | for (i = 0; i < DEPTH_X_RES * DEPTH_Y_RES * sizeof(uint16_t) / sizeof(size_t); i++) wipe[i] = DEPTH_NO_MM_VALUE;
|
110 | 92 |
|
111 |
| - uint16_t unpack[8]; |
| 93 | + uint16_t unpack[8] = { 0 }; |
112 | 94 |
|
113 | 95 | uint32_t target_offset = DEPTH_Y_RES * reg->reg_pad_info.start_lines;
|
114 | 96 | uint32_t x,y,source_index = 8;
|
115 | 97 |
|
116 | 98 | for (y = 0; y < DEPTH_Y_RES; y++) {
|
117 | 99 | for (x = 0; x < DEPTH_X_RES; x++) {
|
118 | 100 |
|
119 |
| - uint16_t metric_depth; |
120 |
| - |
121 |
| - if (unpacked) { |
122 |
| - uint32_t buf_index = y * DEPTH_X_RES + x; |
123 |
| - metric_depth = reg->raw_to_mm_shift[((uint16_t *)input)[buf_index]]; |
124 |
| - } else { |
125 |
| - // get 8 pixels from the packed frame |
126 |
| - if (source_index == 8) { |
127 |
| - unpack_8_pixels( input, unpack ); |
128 |
| - source_index = 0; |
129 |
| - input += 11; |
130 |
| - } |
131 |
| - |
132 |
| - // get the value at the current depth pixel, convert to millimeters |
133 |
| - metric_depth = reg->raw_to_mm_shift[ unpack[source_index++] ]; |
134 |
| - } |
| 101 | + uint16_t metric_depth; |
| 102 | + |
| 103 | + switch (input_mode.depth_format) { |
| 104 | + case FREENECT_DEPTH_MM: |
| 105 | + uint32_t buf_index = (y * input_mode.width) + x; |
| 106 | + metric_depth = ((uint16_t *)input)[buf_index]; |
| 107 | + break; |
| 108 | + case FREENECT_DEPTH_11BIT: // as used by fakenect-record |
| 109 | + case FREENECT_DEPTH_10BIT: // todo: does this work? |
| 110 | + uint32_t buf_index = (y * input_mode.width) + x; |
| 111 | + metric_depth = reg->raw_to_mm_shift[((uint16_t *)input)[buf_index]]; |
| 112 | + break; |
| 113 | + case FREENECT_DEPTH_11BIT_PACKED: |
| 114 | + case FREENECT_DEPTH_10BIT_PACKED: |
| 115 | + // get 8 pixels from the packed frame |
| 116 | + if (source_index == 8) { |
| 117 | + convert_packed_to_16bit(input, unpack, input_mode.data_bits_per_pixel, 8); |
| 118 | + source_index = 0; |
| 119 | + input += 11; |
| 120 | + } |
| 121 | + // get the value at the current depth pixel, convert to millimeters |
| 122 | + metric_depth = reg->raw_to_mm_shift[ unpack[source_index++] ]; |
| 123 | + break; |
| 124 | + default: |
| 125 | + return -99; |
| 126 | + } |
135 | 127 |
|
136 | 128 | // so long as the current pixel has a depth value
|
137 | 129 | if (metric_depth == DEPTH_NO_MM_VALUE) continue;
|
@@ -175,17 +167,29 @@ FN_INTERNAL int freenect_apply_registration(freenect_device* dev, uint8_t* input
|
175 | 167 | return 0;
|
176 | 168 | }
|
177 | 169 |
|
| 170 | +FREENECTAPI int freenect_map_depth_to_video(freenect_device* dev, void* input, uint16_t* output_mm) |
| 171 | +{ |
| 172 | + if (!dev || !input || !output_mm) return -1; |
| 173 | + |
| 174 | + if (!dev->registration.registration_table) { |
| 175 | + freenect_init_registration(dev); |
| 176 | + } |
| 177 | + const freenect_registration* reg = &(dev->registration); |
| 178 | + const freenect_frame_mode depth_mode = freenect_get_current_depth_mode(dev); |
| 179 | + return freenect_apply_registration(reg, depth_mode, input, output_mm); |
| 180 | +} |
| 181 | + |
178 | 182 | // Same as freenect_apply_registration, but don't bother aligning to the RGB image
|
179 | 183 | FN_INTERNAL int freenect_apply_depth_to_mm(freenect_device* dev, uint8_t* input_packed, uint16_t* output_mm)
|
180 | 184 | {
|
181 | 185 | freenect_registration* reg = &(dev->registration);
|
182 |
| - uint16_t unpack[8]; |
| 186 | + uint16_t unpack[8] = { 0 }; |
183 | 187 | uint32_t x,y,source_index = 8;
|
184 | 188 | for (y = 0; y < DEPTH_Y_RES; y++) {
|
185 | 189 | for (x = 0; x < DEPTH_X_RES; x++) {
|
186 | 190 | // get 8 pixels from the packed frame
|
187 | 191 | if (source_index == 8) {
|
188 |
| - unpack_8_pixels( input_packed, unpack ); |
| 192 | + convert_packed_to_16bit(input_packed, output_mm, 11, 8); |
189 | 193 | source_index = 0;
|
190 | 194 | input_packed += 11;
|
191 | 195 | }
|
|
0 commit comments