ipedec.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <sys/time.h>
  8. #include <getopt.h>
  9. #include <ufodecode.h>
  10. typedef struct {
  11. int clear_frame;
  12. int dry_run;
  13. int verbose;
  14. int rows;
  15. int print_frame_rate;
  16. int print_num_rows;
  17. } Options;
  18. static int
  19. read_raw_file(const char *filename, char **buffer, size_t *length)
  20. {
  21. FILE *fp = fopen(filename, "rb");
  22. if (fp == NULL)
  23. return ENOENT;
  24. fseek(fp, 0, SEEK_END);
  25. *length = ftell(fp);
  26. rewind(fp);
  27. *buffer = (char *) malloc(*length);
  28. if (*buffer == NULL) {
  29. fclose(fp);
  30. return ENOMEM;
  31. }
  32. size_t buffer_length = fread(*buffer, 1, *length, fp);
  33. fclose(fp);
  34. if (buffer_length != *length) {
  35. free(*buffer);
  36. return ERANGE;
  37. }
  38. return 0;
  39. }
  40. static void
  41. usage(void)
  42. {
  43. printf("usage: ipedec [OPTION]... FILE [FILE ...]\n\
  44. Options:\n\
  45. -h, --help Show this help message and exit\n\
  46. -v, --verbose Print additional information on STDOUT\n\
  47. -r, --num-rows=N N rows that are contained in the file\n\
  48. -c, --clear-frame Clear the frame for each iteration\n\
  49. -d, --dry-run Do not save the frames\n\
  50. -f, --print-frame-rate Print frame rate on STDOUT\n\
  51. --print-num-rows Print number of rows on STDOUT\n");
  52. }
  53. static void
  54. print_meta_data (UfoDecoderMeta *meta)
  55. {
  56. printf(" frame_number = %i\n", meta->frame_number);
  57. printf(" time_stamp = %i\n", meta->time_stamp);
  58. printf(" output_mode = %i\n", meta->output_mode);
  59. printf(" adc_resolution = %i\n", meta->adc_resolution);
  60. printf(" n_rows = %i\n", meta->n_rows);
  61. printf(" n_skipped_rows = %i\n", meta->n_skipped_rows);
  62. printf(" status1\n");
  63. printf(" fsm_master_readout = %i\n", meta->status1.desc.fsm_master_readout);
  64. printf(" fsm_daq = %i\n", meta->status1.desc.fsm_daq);
  65. printf(" pixel_full = %i\n", meta->status1.desc.pixel_full);
  66. printf(" control_lock = %i\n", meta->status1.desc.control_lock);
  67. printf(" data_lock = %i\n", meta->status1.desc.data_lock);
  68. printf(" status2\n");
  69. printf(" end_of_frames = %i\n", meta->status2.desc.end_of_frames);
  70. printf(" busy_or = %i\n", meta->status2.desc.busy_or);
  71. printf(" busy_ddr = %i\n", meta->status2.desc.busy_ddr);
  72. printf(" busy_interl = %i\n", meta->status2.desc.busy_interl);
  73. printf(" error_status = %i\n", meta->status2.desc.error_status);
  74. printf(" data_fifo_read_count = %i\n", meta->status2.desc.data_fifo_read_count);
  75. printf(" data_fifo_full = %i\n", meta->status2.desc.data_fifo_full);
  76. printf(" data_fifo_empty = %i\n", meta->status2.desc.data_fifo_empty);
  77. printf(" ddr_fifo_write_count = %i\n", meta->status2.desc.ddr_fifo_write_count);
  78. printf(" ddr_fifo_full = %i\n", meta->status2.desc.ddr_fifo_full);
  79. printf(" ddr_fifo_empty = %i\n", meta->status2.desc.ddr_fifo_empty);
  80. printf(" status3\n");
  81. printf(" row_counter = %i\n", meta->status3.desc.row_counter);
  82. printf(" pixel_counter = %i\n", meta->status3.desc.pixel_counter);
  83. printf(" ddr_read = %i\n", meta->status3.desc.ddr_read);
  84. printf(" ddr_write = %i\n", meta->status3.desc.ddr_write);
  85. printf(" ddr_arbiter = %i\n", meta->status3.desc.ddr_arbiter);
  86. printf("\n");
  87. }
  88. typedef struct {
  89. struct timeval start;
  90. long seconds;
  91. long useconds;
  92. } Timer;
  93. static Timer *
  94. timer_new (void)
  95. {
  96. Timer *t = (Timer *) malloc (sizeof (Timer));
  97. t->seconds = t->useconds = 0L;
  98. return t;
  99. }
  100. static void
  101. timer_destroy (Timer *t)
  102. {
  103. free (t);
  104. }
  105. static void
  106. timer_start (Timer *t)
  107. {
  108. gettimeofday(&t->start, NULL);
  109. }
  110. static void
  111. timer_stop (Timer *t)
  112. {
  113. struct timeval end;
  114. gettimeofday(&end, NULL);
  115. t->seconds += end.tv_sec - t->start.tv_sec;
  116. t->useconds += end.tv_usec - t->start.tv_usec;
  117. }
  118. static int
  119. process_file(const char *filename, Options *opts)
  120. {
  121. UfoDecoder *decoder;
  122. UfoDecoderMeta meta = {0};
  123. Timer *timer;
  124. char *buffer;
  125. size_t num_bytes;
  126. uint16_t *pixels;
  127. uint32_t time_stamp, old_time_stamp;
  128. int n_frames;
  129. int error = 0;
  130. FILE *fp;
  131. char output_name[256];
  132. float mtime;
  133. error = read_raw_file(filename, &buffer, &num_bytes);
  134. if (error) {
  135. fprintf(stderr, "Error reading %s: %s\n", filename, strerror(error));
  136. return error;
  137. }
  138. decoder = ufo_decoder_new(opts->rows, 2048, (uint32_t *) buffer, num_bytes);
  139. if (decoder == NULL) {
  140. fprintf(stderr, "Failed to initialize decoder\n");
  141. return 1;
  142. }
  143. if (!opts->dry_run) {
  144. snprintf(output_name, 256, "%s.raw", filename);
  145. fp = fopen(output_name, "wb");
  146. if (!fp) {
  147. fprintf(stderr, "Failed to open file for writing\n");
  148. return 1;
  149. }
  150. }
  151. timer = timer_new ();
  152. pixels = (uint16_t *) malloc(2048 * 1088 * sizeof(uint16_t));
  153. n_frames = 0;
  154. old_time_stamp = 0;
  155. while (error != EIO) {
  156. if (opts->clear_frame)
  157. memset(pixels, 0, 2048 * 1088 * sizeof(uint16_t));
  158. timer_start (timer);
  159. error = ufo_decoder_get_next_frame(decoder, &pixels, &meta);
  160. timer_stop (timer);
  161. if (!error) {
  162. n_frames++;
  163. if (opts->verbose) {
  164. printf("Status for frame %i\n", n_frames);
  165. print_meta_data (&meta);
  166. }
  167. if (opts->print_frame_rate) {
  168. uint32_t diff = 80 * (meta.time_stamp - old_time_stamp);
  169. printf("%-6d", 1000000000 / diff);
  170. old_time_stamp = meta.time_stamp;
  171. }
  172. if (opts->print_num_rows)
  173. printf("%d", meta.n_rows);
  174. if (opts->print_frame_rate || opts->print_num_rows)
  175. printf("\n");
  176. if (!opts->dry_run)
  177. fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
  178. }
  179. else if (error != EIO) {
  180. fprintf(stderr, "Failed to decode frame %i\n", n_frames);
  181. break;
  182. }
  183. }
  184. if (!opts->dry_run)
  185. fclose(fp);
  186. if (opts->verbose) {
  187. mtime = timer->seconds * 1000.0 + timer->useconds / 1000.0;
  188. printf("Decoded %i frames in %.5fms\n", n_frames, mtime);
  189. }
  190. free(pixels);
  191. free(buffer);
  192. timer_destroy (timer);
  193. ufo_decoder_free(decoder);
  194. return error == EIO ? 0 : error;
  195. }
  196. int main(int argc, char const* argv[])
  197. {
  198. int getopt_ret, index;
  199. enum {
  200. CLEAR_FRAME = 'c',
  201. DRY_RUN = 'd',
  202. FRAME_RATE = 'f',
  203. HELP = 'h',
  204. SET_NUM_ROWS = 'r',
  205. VERBOSE = 'v',
  206. NUM_ROWS
  207. };
  208. static struct option long_options[] = {
  209. { "num-rows", required_argument, 0, SET_NUM_ROWS },
  210. { "clear-frame", no_argument, 0, CLEAR_FRAME },
  211. { "verbose", no_argument, 0, VERBOSE },
  212. { "help", no_argument, 0, HELP },
  213. { "dry-run", no_argument, 0, DRY_RUN },
  214. { "print-frame-rate", no_argument, 0, FRAME_RATE },
  215. { "print-num-rows", no_argument, 0, NUM_ROWS },
  216. { 0, 0, 0, 0 }
  217. };
  218. static Options opts = {
  219. .rows = 1088,
  220. .verbose = 0,
  221. .dry_run = 0,
  222. .clear_frame = 0,
  223. .print_frame_rate = 0,
  224. .print_num_rows = 0
  225. };
  226. while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:cvhdf", long_options, &index)) != -1) {
  227. switch (getopt_ret) {
  228. case SET_NUM_ROWS:
  229. opts.rows = atoi(optarg);
  230. break;
  231. case CLEAR_FRAME:
  232. opts.clear_frame = 1;
  233. break;
  234. case VERBOSE:
  235. opts.verbose = 1;
  236. break;
  237. case HELP:
  238. usage();
  239. return 0;
  240. case DRY_RUN:
  241. opts.dry_run = 1;
  242. break;
  243. case FRAME_RATE:
  244. opts.print_frame_rate = 1;
  245. break;
  246. case NUM_ROWS:
  247. opts.print_num_rows = 1;
  248. default:
  249. break;
  250. }
  251. }
  252. if (optind == argc) {
  253. printf("ipedec: no input files\n");
  254. return 1;
  255. }
  256. while (optind < argc) {
  257. int errcode = process_file(argv[optind++], &opts);
  258. if (errcode != 0)
  259. return errcode;
  260. }
  261. return 0;
  262. }