ufodecode.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include "ufodecode.h"
  6. #include "ufodecode-private.h"
  7. #include "config.h"
  8. #ifdef HAVE_SSE
  9. #include <xmmintrin.h>
  10. #endif
  11. #define CHECKS
  12. #ifdef DEBUG
  13. # define SLOW_CHECKS
  14. # define ALL_CHECKS
  15. # define VERBOSE
  16. #endif /* DEBUG */
  17. #ifdef ALL_CHECKS
  18. # undef HAVE_SSE
  19. #endif /* ALL_CHECKS */
  20. #define IPECAMERA_NUM_ROWS 1088
  21. #define IPECAMERA_NUM_CHANNELS 16 /**< Number of channels per row */
  22. #define IPECAMERA_PIXELS_PER_CHANNEL 128 /**< Number of pixels per channel */
  23. #define IPECAMERA_WIDTH (IPECAMERA_NUM_CHANNELS * IPECAMERA_PIXELS_PER_CHANNEL) /**< Total pixel width of row */
  24. #define IPECAMERA_MODE_16_CHAN_IO 0
  25. #define IPECAMERA_MODE_4_CHAN_IO 2
  26. #define IPECAMERA_MODE_12_BIT_ADC 2
  27. #define IPECAMERA_MODE_11_BIT_ADC 1
  28. #define IPECAMERA_MODE_10_BIT_ADC 0
  29. typedef struct {
  30. unsigned int pixel_number : 8;
  31. unsigned int row_number : 12;
  32. unsigned int pixel_size : 4;
  33. unsigned int magic : 8;
  34. } payload_header_v5;
  35. /**
  36. * Check if value matches expected input.
  37. */
  38. #ifdef VERBOSE
  39. # define CHECK_VALUE(value, expected) \
  40. if (value != expected) { \
  41. fprintf(stderr, "<%s:%i> 0x%x != 0x%x\n", __FILE__, __LINE__, value, expected); \
  42. err = 1; \
  43. }
  44. #else
  45. # define CHECK_VALUE(value, expected) \
  46. if (value != expected) { \
  47. err = 1; \
  48. }
  49. #endif
  50. /**
  51. * Check that flag evaluates to non-zero.
  52. */
  53. #ifdef VERBOSE
  54. # define CHECK_FLAG(flag, check, ...) \
  55. if (!(check)) { \
  56. fprintf(stderr, "<%s:%i> Unexpected value 0x%x of " flag "\n", __FILE__, __LINE__, __VA_ARGS__); \
  57. err = 1; \
  58. }
  59. #else
  60. # define CHECK_FLAG(flag, check, ...) \
  61. if (!(check)) { \
  62. err = 1; \
  63. }
  64. #endif
  65. /**
  66. * \brief Setup a new decoder instance
  67. *
  68. * \param height Number of rows that are expected in the data stream. Set this
  69. * smaller 0 to let the decoder figure out the number of rows.
  70. * \param raw The data stream from the camera or NULL if set later with
  71. * ufo_decoder_set_raw_data.
  72. * \param num_bytes Size of the data stream buffer in bytes
  73. *
  74. * \return A new decoder instance that can be used to iterate over the frames
  75. * using ufo_decoder_get_next_frame.
  76. */
  77. UfoDecoder *
  78. ufo_decoder_new (int32_t height, uint32_t width, uint32_t *raw, size_t num_bytes)
  79. {
  80. if (width % IPECAMERA_PIXELS_PER_CHANNEL)
  81. return NULL;
  82. UfoDecoder *decoder = malloc(sizeof(UfoDecoder));
  83. if (decoder == NULL)
  84. return NULL;
  85. decoder->width = width;
  86. decoder->height = height;
  87. ufo_decoder_set_raw_data(decoder, raw, num_bytes);
  88. return decoder;
  89. }
  90. /**
  91. * \brief Release decoder instance
  92. *
  93. * \param decoder An UfoDecoder instance
  94. */
  95. void
  96. ufo_decoder_free(UfoDecoder *decoder)
  97. {
  98. free(decoder);
  99. }
  100. /**
  101. * \brief Set raw data stream
  102. *
  103. * \param decoder An UfoDecoder instance
  104. * \param raw Raw data stream
  105. * \param num_bytes Size of data stream buffer in bytes
  106. */
  107. void
  108. ufo_decoder_set_raw_data(UfoDecoder *decoder, uint32_t *raw, size_t num_bytes)
  109. {
  110. decoder->raw = raw;
  111. decoder->num_bytes = num_bytes;
  112. decoder->current_pos = 0;
  113. }
  114. static int
  115. ufo_decode_frame_channels_v0(UfoDecoder *decoder,
  116. uint16_t *pixel_buffer,
  117. uint32_t *raw,
  118. size_t num_words,
  119. size_t *offset)
  120. {
  121. static int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 };
  122. static int channel_size = (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3);
  123. const int bytes = channel_size - 1;
  124. const int num_rows = decoder->height;
  125. const size_t cpl = (decoder->width / IPECAMERA_PIXELS_PER_CHANNEL);
  126. const size_t cpi = num_rows * cpl;
  127. int pos = 0;
  128. uint32_t data;
  129. #ifdef HAVE_SSE
  130. __m128i mask = _mm_set_epi32(0x3FF, 0x3FF, 0x3FF, 0x3FF);
  131. __m128i packed;
  132. __m128i tmp1, tmp2;
  133. uint32_t result[4] __attribute__ ((aligned (16))) = {0};
  134. #endif
  135. if (cpi * channel_size > num_words) {
  136. #ifdef VERBOSE
  137. fprintf(stderr, "Not enough data to decode frame, expected %lu bytes, but received %lu\n", cpi * channel_size * sizeof(uint32_t), num_words * sizeof(uint32_t));
  138. #endif
  139. return EILSEQ;
  140. }
  141. for (size_t c = 0; c < cpi; c++) {
  142. const int info = raw[0];
  143. int row = (info >> 4) & 0x7FF;
  144. int channel = info & 0x0F;
  145. int pixels = (info >> 20) & 0xFF;
  146. #ifdef SLOW_CHECKS
  147. int header = (info >> 30) & 0x03;
  148. const int bpp = (info >> 16) & 0x0F;
  149. int err;
  150. CHECK_FLAG("raw header magick", header == 2, header);
  151. CHECK_FLAG("row number, only %i rows requested", row < num_rows, row, num_rows);
  152. CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
  153. CHECK_FLAG("channel, limited by %zu output channels", channel < cpl, channel, cpl);
  154. #endif
  155. if ((row > num_rows) || (channel > cpl) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
  156. return EILSEQ;
  157. channel = channel_order[channel];
  158. int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
  159. /* "Correct" missing pixel */
  160. if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
  161. pixel_buffer[base] = 0;
  162. /* base++; */
  163. }
  164. #ifdef SLOW_CHECKS
  165. else
  166. CHECK_FLAG("number of pixels, %i is expected", pixels == IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL);
  167. #endif
  168. #ifdef HAVE_SSE
  169. for (int i = 1 ; i < bytes-4; i += 4, base += 12) {
  170. packed = _mm_set_epi32(raw[i], raw[i+1], raw[i+2], raw[i+3]);
  171. tmp1 = _mm_srli_epi32(packed, 20);
  172. tmp2 = _mm_and_si128(tmp1, mask);
  173. _mm_storeu_si128((__m128i*) result, tmp2);
  174. pixel_buffer[base+0] = result[3];
  175. pixel_buffer[base+3] = result[2];
  176. pixel_buffer[base+6] = result[1];
  177. pixel_buffer[base+9] = result[0];
  178. tmp1 = _mm_srli_epi32(packed, 10);
  179. tmp2 = _mm_and_si128(tmp1, mask);
  180. _mm_storeu_si128((__m128i*) result, tmp2);
  181. pixel_buffer[base+1] = result[3];
  182. pixel_buffer[base+4] = result[2];
  183. pixel_buffer[base+7] = result[1];
  184. pixel_buffer[base+10] = result[0];
  185. tmp1 = _mm_and_si128(packed, mask);
  186. _mm_storeu_si128((__m128i*) result, tmp1);
  187. pixel_buffer[base+2] = result[3];
  188. pixel_buffer[base+5] = result[2];
  189. pixel_buffer[base+8] = result[1];
  190. pixel_buffer[base+11] = result[0];
  191. }
  192. /* Compute last pixels by hand */
  193. data = raw[41];
  194. pixel_buffer[base++] = (data >> 20) & 0x3FF;
  195. pixel_buffer[base++] = (data >> 10) & 0x3FF;
  196. pixel_buffer[base++] = data & 0x3FF;
  197. data = raw[42];
  198. pixel_buffer[base++] = (data >> 20) & 0x3FF;
  199. pixel_buffer[base++] = (data >> 10) & 0x3FF;
  200. pixel_buffer[base++] = data & 0x3FF;
  201. #else
  202. for (int i = 1 ; i < bytes; i++) {
  203. data = raw[i];
  204. # ifdef SLOW_CHECKS
  205. header = (data >> 30) & 0x03;
  206. CHECK_FLAG("raw data magic", header == 3, header);
  207. if (err)
  208. return err;
  209. # endif
  210. pixel_buffer[base++] = (data >> 20) & 0x3FF;
  211. pixel_buffer[base++] = (data >> 10) & 0x3FF;
  212. pixel_buffer[base++] = data & 0x3FF;
  213. }
  214. #endif
  215. data = raw[bytes];
  216. #ifdef SLOW_CHECKS
  217. header = (data >> 30) & 0x03;
  218. CHECK_FLAG("raw data magic", header == 3, header);
  219. CHECK_FLAG("raw footer magic", (data & 0x3FF) == 0x55, (data & 0x3FF));
  220. if (err)
  221. return err;
  222. #endif
  223. int ppw = pixels >> 6;
  224. for (int j = 0; j < ppw; j++)
  225. pixel_buffer[base++] = (data >> (10 * (ppw - j))) & 0x3FF;
  226. pos += channel_size;
  227. raw += channel_size;
  228. }
  229. *offset += pos;
  230. return 0;
  231. }
  232. static int
  233. ufo_decode_frame_channels_v4(UfoDecoder *decoder,
  234. uint16_t *pixel_buffer,
  235. uint32_t *raw,
  236. size_t num_words,
  237. size_t num_rows,
  238. size_t *offset)
  239. {
  240. static const int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 };
  241. static const int channel_size = (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3);
  242. const int bytes = channel_size - 1;
  243. const size_t channels_per_row = (decoder->width / IPECAMERA_PIXELS_PER_CHANNEL);
  244. const size_t cpi = num_rows * channels_per_row;
  245. int pos = 0;
  246. uint32_t data;
  247. #ifdef HAVE_SSE
  248. __m128i mask = _mm_set_epi32(0x3FF, 0x3FF, 0x3FF, 0x3FF);
  249. __m128i packed;
  250. __m128i tmp1, tmp2;
  251. uint32_t result[4] __attribute__ ((aligned (16))) = {0};
  252. #endif
  253. if (cpi * channel_size > num_words) {
  254. #ifdef VERBOSE
  255. fprintf(stderr, "Not enough data to decode frame, expected %lu bytes, but received %lu\n", cpi * channel_size * sizeof(uint32_t), num_words * sizeof(uint32_t));
  256. #endif
  257. return EILSEQ;
  258. }
  259. for (size_t c = 0; c < cpi; c++) {
  260. int err = 0;
  261. const int info = raw[0];
  262. int row = (info >> 4) & 0x7FF;
  263. int channel = info & 0x0F;
  264. int pixels = (info >> 20) & 0xFF;
  265. #ifdef SLOW_CHECKS
  266. int header = (info >> 30) & 0x03;
  267. const int bpp = (info >> 16) & 0x0F;
  268. CHECK_FLAG("raw header magick", header == 2, header);
  269. CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
  270. #endif
  271. CHECK_FLAG("pixels, only %u pixels per channel (offset: %zx)", pixels <= IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL, (*offset + pos));
  272. CHECK_FLAG("channel, limited by %zu output channels (offset: %zx)", channel <= channels_per_row, channel, channels_per_row, (*offset + pos));
  273. if (err)
  274. return EILSEQ;
  275. channel = channel_order[channel];
  276. int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
  277. /* "Correct" missing pixel */
  278. if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
  279. pixel_buffer[base] = 0;
  280. /* base++; */
  281. }
  282. #ifdef HAVE_SSE
  283. for (int i = 1 ; i < bytes-4; i += 4, base += 12) {
  284. packed = _mm_set_epi32(raw[i], raw[i+1], raw[i+2], raw[i+3]);
  285. tmp1 = _mm_srli_epi32(packed, 20);
  286. tmp2 = _mm_and_si128(tmp1, mask);
  287. _mm_storeu_si128((__m128i*) result, tmp2);
  288. pixel_buffer[base+0] = result[3];
  289. pixel_buffer[base+3] = result[2];
  290. pixel_buffer[base+6] = result[1];
  291. pixel_buffer[base+9] = result[0];
  292. tmp1 = _mm_srli_epi32(packed, 10);
  293. tmp2 = _mm_and_si128(tmp1, mask);
  294. _mm_storeu_si128((__m128i*) result, tmp2);
  295. pixel_buffer[base+1] = result[3];
  296. pixel_buffer[base+4] = result[2];
  297. pixel_buffer[base+7] = result[1];
  298. pixel_buffer[base+10] = result[0];
  299. tmp1 = _mm_and_si128(packed, mask);
  300. _mm_storeu_si128((__m128i*) result, tmp1);
  301. pixel_buffer[base+2] = result[3];
  302. pixel_buffer[base+5] = result[2];
  303. pixel_buffer[base+8] = result[1];
  304. pixel_buffer[base+11] = result[0];
  305. }
  306. /* Compute last pixels by hand */
  307. data = raw[41];
  308. pixel_buffer[base++] = (data >> 20) & 0x3FF;
  309. pixel_buffer[base++] = (data >> 10) & 0x3FF;
  310. pixel_buffer[base++] = data & 0x3FF;
  311. data = raw[42];
  312. pixel_buffer[base++] = (data >> 20) & 0x3FF;
  313. pixel_buffer[base++] = (data >> 10) & 0x3FF;
  314. pixel_buffer[base++] = data & 0x3FF;
  315. #else
  316. for (int i = 1 ; i < bytes; i++) {
  317. data = raw[i];
  318. # ifdef SLOW_CHECKS
  319. header = (data >> 30) & 0x03;
  320. CHECK_FLAG("raw data magic (offset: 0x%zx, expected: 0x02)", header == 3, header, (*offset + pos + i)*sizeof(uint32_t));
  321. if (err)
  322. return err;
  323. # endif
  324. pixel_buffer[base++] = (data >> 20) & 0x3FF;
  325. pixel_buffer[base++] = (data >> 10) & 0x3FF;
  326. pixel_buffer[base++] = data & 0x3FF;
  327. }
  328. #endif
  329. data = raw[bytes];
  330. #ifdef SLOW_CHECKS
  331. header = (data >> 30) & 0x03;
  332. CHECK_FLAG("raw data magic (offset: 0x%zx, expected: 0x03)", header == 3, header, (*offset + pos + bytes)*sizeof(uint32_t));
  333. CHECK_FLAG("raw footer magic (offset: 0x%zx, expected: 0x55)", (data & 0x3FF) == 0x55, (data & 0x3FF), (*offset + pos + bytes)*sizeof(uint32_t));
  334. if (err)
  335. return err;
  336. #endif
  337. int ppw = pixels >> 6;
  338. for (int j = 0; j < ppw; j++)
  339. pixel_buffer[base++] = (data >> (10 * (ppw - j))) & 0x3FF;
  340. pos += channel_size;
  341. raw += channel_size;
  342. }
  343. *offset += pos;
  344. return 0;
  345. }
  346. static int
  347. ufo_decode_frame_channels_v5(UfoDecoder *decoder,
  348. uint16_t *pixel_buffer,
  349. uint32_t *raw,
  350. size_t num_rows,
  351. size_t *offset,
  352. uint8_t output_mode)
  353. {
  354. payload_header_v5 *header;
  355. size_t base = 0, index = 0;
  356. header = (payload_header_v5 *) &raw[base];
  357. if (output_mode == IPECAMERA_MODE_4_CHAN_IO) {
  358. size_t off = 0;
  359. while (raw[base] != 0xAAAAAAA) {
  360. header = (payload_header_v5 *) &raw[base];
  361. index = header->row_number * IPECAMERA_WIDTH + header->pixel_number;
  362. /* Skip header + one zero-filled words */
  363. base += 2;
  364. if ((header->magic != 0xe0) && (header->magic != 0xc0)) {
  365. pixel_buffer[index + (0+off)*IPECAMERA_PIXELS_PER_CHANNEL] = 0xfff & (raw[base+5] >> 12);
  366. pixel_buffer[index + (4+off)*IPECAMERA_PIXELS_PER_CHANNEL] = 0xfff & (raw[base+4] >> 4);
  367. pixel_buffer[index + (8+off)*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xf & raw[base+1]) << 8) | (raw[base+2] >> 24);
  368. pixel_buffer[index + (12+off)*IPECAMERA_PIXELS_PER_CHANNEL] = 0xfff & (raw[base+1] >> 16);
  369. }
  370. else {
  371. off++;
  372. if (header->magic == 0xc0)
  373. off = 0;
  374. }
  375. base += 6;
  376. }
  377. }
  378. else {
  379. while (raw[base] != 0xAAAAAAA) {
  380. header = (payload_header_v5 *) &raw[base];
  381. index = header->row_number * IPECAMERA_WIDTH + header->pixel_number;
  382. /* Skip header + two zero-filled words */
  383. base += 2;
  384. if (header->magic != 0xc0) {
  385. pixel_buffer[index + 15*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 20);
  386. pixel_buffer[index + 13*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 8);
  387. pixel_buffer[index + 14*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (((0xff & raw[base]) << 4) | (raw[base+1] >> 28));
  388. pixel_buffer[index + 12*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 16);
  389. pixel_buffer[index + 10*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 4);
  390. pixel_buffer[index + 8*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3 & raw[base+1]) << 8) | (raw[base+2] >> 24);
  391. pixel_buffer[index + 11*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 12);
  392. pixel_buffer[index + 7*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+2];
  393. pixel_buffer[index + 9*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 20);
  394. pixel_buffer[index + 6*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 8);
  395. pixel_buffer[index + 5*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (((0xff & raw[base+3]) << 4) | (raw[base+4] >> 28));
  396. pixel_buffer[index + 2*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 16);
  397. pixel_buffer[index + 4*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 4);
  398. pixel_buffer[index + 3*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3 & raw[base+4]) << 8) | (raw[base+5] >> 24);
  399. pixel_buffer[index + 0*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+5] >> 12);
  400. pixel_buffer[index + 1*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+5];
  401. }
  402. base += 6;
  403. }
  404. }
  405. *offset += base;
  406. return 0;
  407. }
  408. /**
  409. * \brief Deinterlace by interpolating between two rows
  410. *
  411. * \param in Input frame
  412. * \param out Destination of interpolated frame
  413. * \param width Width of frame in pixels
  414. * \param height Height of frame in pixels
  415. */
  416. void ufo_deinterlace_interpolate(const uint16_t *in, uint16_t *out, int width, int height)
  417. {
  418. const size_t row_size_bytes = width * sizeof(uint16_t);
  419. for (int row = 0; row < height; row++) {
  420. /* Copy one line */
  421. memcpy(out, in + row*width, row_size_bytes);
  422. out += width;
  423. /* Interpolate between source row and row+1 */
  424. for (int x = 0; x < width; x++)
  425. out[x] = (int) (0.5 * in[row*width + x] + 0.5 * in[(row+1)*width + x]);
  426. out += width;
  427. }
  428. /* Copy last row */
  429. memcpy(out, in + width * (height - 1), row_size_bytes);
  430. }
  431. /**
  432. * \brief Deinterlace by "weaving" the rows of two frames
  433. *
  434. * \param in1 First frame
  435. * \param in2 Second frame
  436. * \param out Destination of weaved frame
  437. * \param width Width of frame in pixels
  438. * \param height Height of frame in pixels
  439. */
  440. void ufo_deinterlace_weave(const uint16_t *in1, const uint16_t *in2, uint16_t *out, int width, int height)
  441. {
  442. const size_t row_size_bytes = width * sizeof(uint16_t);
  443. for (int row = 0; row < height; row++) {
  444. memcpy(out, in1 + row*width, row_size_bytes);
  445. out += width;
  446. memcpy(out, in2 + row*width, row_size_bytes);
  447. out += width;
  448. }
  449. }
  450. /**
  451. * \brief Decodes frame
  452. *
  453. * This function tries to decode the supplied data
  454. *
  455. * \param decoder An UfoDecoder instance
  456. * \param raw Raw data stream
  457. * \param num_bytes Size of data stream buffer in bytes
  458. * \param pixels If pointer with NULL content is passed, a new buffer is
  459. * allocated otherwise, this user-supplied buffer is used.
  460. * \param frame_number Frame number as reported in the header
  461. * \param time_stamp Time stamp of the frame as reported in the header
  462. *
  463. * \return number of decoded bytes or 0 in case of error
  464. */
  465. size_t ufo_decoder_decode_frame(UfoDecoder *decoder,
  466. uint32_t *raw,
  467. size_t num_bytes,
  468. uint16_t *pixels,
  469. UfoDecoderMeta *meta)
  470. {
  471. int err = 0;
  472. size_t pos = 0;
  473. const size_t num_words = num_bytes / 4;
  474. if ((pixels == NULL) || (num_words < 16)) {
  475. #ifdef VERBOSE
  476. if (num_words < 16)
  477. fprintf(stderr, "Not enough frame data, only %zu bytes supplied \n", num_bytes);
  478. #endif
  479. return 0;
  480. }
  481. size_t rows_per_frame = decoder->height;
  482. const int version = (raw[pos+6] >> 24) & 0xF;
  483. #ifdef CHECKS
  484. CHECK_VALUE(raw[pos++], 0x51111111);
  485. CHECK_VALUE(raw[pos++], 0x52222222);
  486. CHECK_VALUE(raw[pos++], 0x53333333);
  487. CHECK_VALUE(raw[pos++], 0x54444444);
  488. CHECK_VALUE(raw[pos++], 0x55555555);
  489. switch (version) {
  490. case 0:
  491. CHECK_VALUE(raw[pos++], 0x56666666);
  492. CHECK_VALUE(raw[pos] >> 28, 0x5);
  493. meta->frame_number = raw[pos++] & 0xFFFFFFF;
  494. CHECK_VALUE(raw[pos] >> 28, 0x5);
  495. meta->time_stamp = raw[pos++] & 0xFFFFFFF;
  496. break;
  497. case 4:
  498. case 5:
  499. CHECK_VALUE(raw[pos] >> 28, 0x5);
  500. meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF;
  501. meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F;
  502. meta->n_rows = rows_per_frame = raw[pos] & 0x7FF;
  503. pos++;
  504. meta->frame_number = raw[pos++] & 0x1FFFFFF;
  505. CHECK_VALUE(raw[pos] >> 28, 0x5);
  506. meta->time_stamp = raw[pos] & 0xFFFFFF;
  507. meta->output_mode = (raw[pos] >> 24) & 0x3;
  508. meta->adc_resolution = (raw[pos] >> 26) & 0x3;
  509. pos++;
  510. if ((meta->output_mode != IPECAMERA_MODE_4_CHAN_IO) && (meta->output_mode != IPECAMERA_MODE_16_CHAN_IO)) {
  511. # ifdef VERBOSE
  512. fprintf(stderr, "Output mode 0x%x is not supported\n", meta->output_mode);
  513. # endif
  514. return 0;
  515. }
  516. break;
  517. default:
  518. # ifdef VERBOSE
  519. fprintf(stderr, "Unsupported data format version %i detected\n", version);
  520. # endif
  521. return 0;
  522. }
  523. if (err)
  524. return 0;
  525. #else
  526. switch (version) {
  527. case 0:
  528. meta->frame_number = raw[pos + 6] & 0xFFFFFFF;
  529. meta->time_stamp = raw[pos + 7] & 0xFFFFFFF;
  530. break;
  531. case 4:
  532. meta->n_rows = rows_per_frame = raw[pos + 5] & 0x7FF;
  533. case 5:
  534. meta->frame_number = raw[pos + 6] & 0x1FFFFFF;
  535. meta->time_stamp = raw[pos + 7] & 0xFFFFFF;
  536. meta->output_mode = (raw[pos + 7] >> 24) & 0x3;
  537. meta->adc_resolution = (raw[pos + 7] >> 26) & 0x3;
  538. break;
  539. default:
  540. # ifdef VERBOSE
  541. fprintf(stderr, "Unsupported data format detected\n");
  542. # endif
  543. return 0;
  544. }
  545. pos += 8;
  546. #endif
  547. switch (version) {
  548. case 0:
  549. err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &pos);
  550. break;
  551. case 4:
  552. err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &pos);
  553. break;
  554. case 5:
  555. err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, rows_per_frame, &pos, meta->output_mode);
  556. break;
  557. default:
  558. break;
  559. }
  560. if (err)
  561. return 0;
  562. #ifdef CHECKS
  563. CHECK_VALUE(raw[pos++], 0x0AAAAAAA);
  564. meta->status1.bits = raw[pos++];
  565. meta->status2.bits = raw[pos++];
  566. meta->status3.bits = raw[pos++];
  567. pos++;
  568. pos++;
  569. CHECK_VALUE(raw[pos++], 0x00000000);
  570. CHECK_VALUE(raw[pos++], 0x01111111);
  571. if (err)
  572. return 0;
  573. #else
  574. pos += 8;
  575. #endif
  576. return pos;
  577. }
  578. /**
  579. * \brief Iterate and decode next frame
  580. *
  581. * This function tries to decode the next frame in the currently set raw data
  582. * stream.
  583. *
  584. * \param decoder An UfoDecoder instance
  585. * \param pixels If pointer with NULL content is passed, a new buffer is
  586. * allocated otherwise, this user-supplied buffer is used.
  587. * \param num_rows Number of actual decoded rows
  588. * \param frame_number Frame number as reported in the header
  589. * \param time_stamp Time stamp of the frame as reported in the header
  590. *
  591. * \return 0 in case of no error, EIO if end of stream was reached, ENOMEM if
  592. * NULL was passed but no memory could be allocated, EILSEQ if data stream is
  593. * corrupt and EFAULT if pixels is a NULL-pointer.
  594. */
  595. int ufo_decoder_get_next_frame(UfoDecoder *decoder,
  596. uint16_t **pixels,
  597. UfoDecoderMeta *meta)
  598. {
  599. uint32_t *raw = decoder->raw;
  600. size_t pos = decoder->current_pos;
  601. size_t advance;
  602. const size_t num_words = decoder->num_bytes / 4;
  603. if (pixels == NULL)
  604. return 0;
  605. if (pos >= num_words)
  606. return EIO;
  607. if (num_words < 16)
  608. return EILSEQ;
  609. if (*pixels == NULL) {
  610. *pixels = (uint16_t *) malloc(IPECAMERA_WIDTH * decoder->height * sizeof(uint16_t));
  611. if (*pixels == NULL)
  612. return ENOMEM;
  613. }
  614. while ((pos < num_words) && (raw[pos] != 0x51111111))
  615. pos++;
  616. advance = ufo_decoder_decode_frame(decoder, raw + pos, decoder->num_bytes - pos, *pixels, meta);
  617. /*
  618. * On error, advance is 0 but we have to advance at least a bit to net get
  619. * caught in an infinite loop when trying to decode subsequent frames.
  620. */
  621. pos += advance == 0 ? 1 : advance;
  622. /* if bytes left and we see fill bytes, skip them */
  623. if (((pos + 2) < num_words) && ((raw[pos] == 0x0) && (raw[pos+1] == 0x1111111))) {
  624. pos += 2;
  625. while ((pos < num_words) && ((raw[pos] == 0x89abcdef) || (raw[pos] == 0x1234567)))
  626. pos++;
  627. }
  628. decoder->current_pos = pos;
  629. if (!advance)
  630. return EILSEQ;
  631. return 0;
  632. }