Go to the documentation of this file.00001
00038 #ifndef LibMultiSense_DisparityMessage
00039 #define LibMultiSense_DisparityMessage
00040
00041 #include <typeinfo>
00042 #include <cmath>
00043
00044 #include "details/utility/Portability.hh"
00045
00046 namespace crl {
00047 namespace multisense {
00048 namespace details {
00049 namespace wire {
00050
00051 class WIRE_HEADER_ATTRIBS_ DisparityHeader {
00052 public:
00053
00054 static CRL_CONSTEXPR IdType ID = ID_DATA_DISPARITY;
00055 static CRL_CONSTEXPR VersionType VERSION = 1;
00056
00057 static CRL_CONSTEXPR uint8_t WIRE_BITS_PER_PIXEL = 12;
00058 static CRL_CONSTEXPR uint8_t WIRE_BYTE_ALIGNMENT = 3;
00059 static CRL_CONSTEXPR uint8_t API_BITS_PER_PIXEL = 16;
00060 static CRL_CONSTEXPR uint32_t META_LENGTH = 16;
00061
00062 #ifdef SENSORPOD_FIRMWARE
00063 IdType id;
00064 VersionType version;
00065 #endif // SENSORPOD_FIRMWARE
00066
00067 int64_t frameId;
00068 uint16_t width;
00069 uint16_t height;
00070
00071 DisparityHeader()
00072 :
00073 #ifdef SENSORPOD_FIRMWARE
00074 id(ID),
00075 version(VERSION),
00076 #endif
00077 frameId(0),
00078 width(0),
00079 height(0) {};
00080 };
00081
00082 #ifndef SENSORPOD_FIRMWARE
00083
00084 class Disparity : public DisparityHeader {
00085 public:
00086
00087 void *dataP;
00088
00089
00090
00091
00092 Disparity(utility::BufferStreamReader&r, VersionType v) {serialize(r,v);};
00093 Disparity() : dataP(NULL) {};
00094
00095
00096
00097
00098 template<class Archive>
00099 void serialize(Archive& message,
00100 const VersionType version)
00101 {
00102 message & frameId;
00103 message & width;
00104 message & height;
00105
00106 const uint32_t imageSize = static_cast<uint32_t> (std::ceil(((double) API_BITS_PER_PIXEL / 8.0) * width * height));
00107
00108 if (typeid(Archive) == typeid(utility::BufferStreamWriter)) {
00109
00110 message.write(dataP, imageSize);
00111
00112 } else {
00113
00114 dataP = message.peek();
00115 message.seek(message.tell() + imageSize);
00116 }
00117 }
00118
00119
00120
00121
00122 static void assembler(utility::BufferStreamWriter& stream,
00123 const uint8_t *dataP,
00124 uint32_t offset,
00125 uint32_t length)
00126 {
00127
00128
00129
00130
00131
00132 if (0 == offset) {
00133 stream.seek(0);
00134 stream.write(dataP, META_LENGTH);
00135 return;
00136 }
00137
00138
00139
00140
00141
00142 const uint8_t *sP = dataP;
00143 const uint32_t sourceOffset = offset - META_LENGTH;
00144 const uint32_t count = (8 * length) / WIRE_BITS_PER_PIXEL;
00145 const uint32_t destOffset = META_LENGTH + (((8 * sourceOffset) / WIRE_BITS_PER_PIXEL) *
00146 (API_BITS_PER_PIXEL / 8));
00147
00148
00149
00150 stream.seek(destOffset);
00151
00152
00153
00154
00155 if (12 == WIRE_BITS_PER_PIXEL && 16 == API_BITS_PER_PIXEL) {
00156
00157 uint16_t *dP = reinterpret_cast<uint16_t*>(stream.peek());
00158
00159 for(uint32_t i=0; i<count; i+=2, sP+=3) {
00160 dP[i] = ((sP[0] ) | ((sP[1] & 0x0F) << 8));
00161 dP[i+1] = ((sP[1] >> 4) | (sP[2] << 4) );
00162 }
00163
00164
00165
00166
00167 } else if (12 == WIRE_BITS_PER_PIXEL && 32 == API_BITS_PER_PIXEL) {
00168
00169 float *dP = reinterpret_cast<float*>(stream.peek());
00170
00171 for(uint32_t i=0; i<count; i+=2, sP+=3) {
00172
00173 dP[i] = static_cast<float>((sP[0] ) | ((sP[1] & 0x0F) << 8)) / 16.0f;
00174 dP[i+1] = static_cast<float>((sP[1] >> 4) | (sP[2] << 4) ) / 16.0f;
00175 }
00176
00177 } else
00178 CRL_EXCEPTION("(wire==%dbits, api=%dbits) not supported",
00179 WIRE_BITS_PER_PIXEL, API_BITS_PER_PIXEL);
00180 }
00181 };
00182
00183 #endif // !SENSORPOD_FIRMWARE
00184
00185 }}}};
00186
00187 #endif