ipedec.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  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. int cont;
  18. int superimpose;
  19. } Options;
  20. static int
  21. read_raw_file(const char *filename, char **buffer, size_t *length)
  22. {
  23. FILE *fp = fopen(filename, "rb");
  24. if (fp == NULL)
  25. return ENOENT;
  26. fseek(fp, 0, SEEK_END);
  27. *length = ftell(fp);
  28. rewind(fp);
  29. *buffer = (char *) malloc(*length);
  30. if (*buffer == NULL) {
  31. fclose(fp);
  32. return ENOMEM;
  33. }
  34. size_t buffer_length = fread(*buffer, 1, *length, fp);
  35. fclose(fp);
  36. if (buffer_length != *length) {
  37. free(*buffer);
  38. return ERANGE;
  39. }
  40. return 0;
  41. }
  42. static void
  43. usage(void)
  44. {
  45. printf("usage: ipedec [OPTION]... FILE [FILE ...]\n\
  46. Options:\n\
  47. -h, --help Show this help message and exit\n\
  48. -v, --verbose Print additional information on STDOUT\n\
  49. -r, --num-rows=N N rows that are contained in the file\n\
  50. -c, --clear-frame Clear the frame for each iteration\n\
  51. -d, --dry-run Do not save the frames\n\
  52. -s, --superimpose=C Superimpose frames on top of the first with color C as borders\n\
  53. -f, --print-frame-rate Print frame rate on STDOUT\n\
  54. --print-num-rows Print number of rows on STDOUT\n\
  55. --continue Continue decoding frames even when errors occur\n");
  56. }
  57. static void
  58. print_meta_data (UfoDecoderMeta *meta)
  59. {
  60. printf(" frame_number = %i\n", meta->frame_number);
  61. printf(" time_stamp = %i\n", meta->time_stamp);
  62. printf(" output_mode = %i\n", meta->output_mode);
  63. printf(" adc_resolution = %i\n", meta->adc_resolution);
  64. printf(" n_rows = %i\n", meta->n_rows);
  65. printf(" n_skipped_rows = %i\n", meta->n_skipped_rows);
  66. printf(" status1\n");
  67. printf(" fsm_master_readout = %i\n", meta->status1.desc.fsm_master_readout);
  68. printf(" fsm_daq = %i\n", meta->status1.desc.fsm_daq);
  69. printf(" pixel_full = %i\n", meta->status1.desc.pixel_full);
  70. printf(" control_lock = %i\n", meta->status1.desc.control_lock);
  71. printf(" data_lock = %i\n", meta->status1.desc.data_lock);
  72. printf(" status2\n");
  73. printf(" end_of_frames = %i\n", meta->status2.desc.end_of_frames);
  74. printf(" busy_or = %i\n", meta->status2.desc.busy_or);
  75. printf(" busy_ddr = %i\n", meta->status2.desc.busy_ddr);
  76. printf(" busy_interl = %i\n", meta->status2.desc.busy_interl);
  77. printf(" error_status = %i\n", meta->status2.desc.error_status);
  78. printf(" data_fifo_read_count = %i\n", meta->status2.desc.data_fifo_read_count);
  79. printf(" data_fifo_full = %i\n", meta->status2.desc.data_fifo_full);
  80. printf(" data_fifo_empty = %i\n", meta->status2.desc.data_fifo_empty);
  81. printf(" ddr_fifo_write_count = %i\n", meta->status2.desc.ddr_fifo_write_count);
  82. printf(" ddr_fifo_full = %i\n", meta->status2.desc.ddr_fifo_full);
  83. printf(" ddr_fifo_empty = %i\n", meta->status2.desc.ddr_fifo_empty);
  84. printf(" status3\n");
  85. printf(" row_counter = %i\n", meta->status3.desc.row_counter);
  86. printf(" pixel_counter = %i\n", meta->status3.desc.pixel_counter);
  87. printf(" ddr_read = %i\n", meta->status3.desc.ddr_read);
  88. printf(" ddr_write = %i\n", meta->status3.desc.ddr_write);
  89. printf(" ddr_arbiter = %i\n", meta->status3.desc.ddr_arbiter);
  90. printf("\n");
  91. }
  92. typedef struct {
  93. struct timeval start;
  94. long seconds;
  95. long useconds;
  96. } Timer;
  97. static Timer *
  98. timer_new (void)
  99. {
  100. Timer *t = (Timer *) malloc (sizeof (Timer));
  101. t->seconds = t->useconds = 0L;
  102. return t;
  103. }
  104. static void
  105. timer_destroy (Timer *t)
  106. {
  107. free (t);
  108. }
  109. static void
  110. timer_start (Timer *t)
  111. {
  112. gettimeofday(&t->start, NULL);
  113. }
  114. static void
  115. timer_stop (Timer *t)
  116. {
  117. struct timeval end;
  118. gettimeofday(&end, NULL);
  119. t->seconds += end.tv_sec - t->start.tv_sec;
  120. t->useconds += end.tv_usec - t->start.tv_usec;
  121. }
  122. static void
  123. superimpose_on_top (uint16_t *top, uint16_t *bottom, uint16_t color)
  124. {
  125. int x, y;
  126. int in_void = top[0] == 0;
  127. for (y = 0; y < 1088; y++) {
  128. int offset = y * 2048;
  129. if ((in_void && top[offset] != 0) ||
  130. (!in_void && top[offset] == 0)) {
  131. in_void = 1 - in_void;
  132. for (x = 0; x < 2048; x++)
  133. top[offset++] = color;
  134. }
  135. else {
  136. for (x = 0; x < 2048; x++, offset++) {
  137. if (top[offset] == 0)
  138. top[offset] = bottom[offset];
  139. }
  140. }
  141. }
  142. }
  143. static int
  144. process_file(const char *filename, Options *opts)
  145. {
  146. UfoDecoder *decoder;
  147. UfoDecoderMeta meta = {0};
  148. Timer *timer;
  149. char *buffer;
  150. size_t num_bytes;
  151. size_t frame_size;
  152. uint16_t *orig;
  153. uint16_t *pixels;
  154. uint32_t time_stamp, old_time_stamp;
  155. int n_frames;
  156. int error = 0;
  157. FILE *fp;
  158. char output_name[256];
  159. float mtime;
  160. frame_size = 2048 * 1088 * sizeof(uint16_t);
  161. error = read_raw_file(filename, &buffer, &num_bytes);
  162. if (error) {
  163. fprintf(stderr, "Error reading %s: %s\n", filename, strerror(error));
  164. return error;
  165. }
  166. decoder = ufo_decoder_new(opts->rows, 2048, (uint32_t *) buffer, num_bytes);
  167. if (decoder == NULL) {
  168. fprintf(stderr, "Failed to initialize decoder\n");
  169. return 1;
  170. }
  171. if (!opts->dry_run) {
  172. snprintf(output_name, 256, "%s.raw", filename);
  173. fp = fopen(output_name, "wb");
  174. if (!fp) {
  175. fprintf(stderr, "Failed to open file for writing\n");
  176. return 1;
  177. }
  178. }
  179. if (opts->superimpose)
  180. orig = (uint16_t *) malloc(frame_size);
  181. pixels = (uint16_t *) malloc(frame_size);
  182. timer = timer_new ();
  183. n_frames = 0;
  184. old_time_stamp = 0;
  185. while (error != EIO) {
  186. if (opts->clear_frame || opts->superimpose)
  187. memset(pixels, 0, frame_size);
  188. timer_start (timer);
  189. error = ufo_decoder_get_next_frame(decoder, &pixels, &meta);
  190. timer_stop (timer);
  191. n_frames++;
  192. if (opts->superimpose && n_frames == 1)
  193. memcpy (orig, pixels, frame_size);
  194. if (!error) {
  195. if (opts->verbose) {
  196. printf("Status for frame %i\n", n_frames);
  197. print_meta_data (&meta);
  198. }
  199. if (opts->print_frame_rate) {
  200. uint32_t diff = 80 * (meta.time_stamp - old_time_stamp);
  201. printf("%-6d", 1000000000 / diff);
  202. old_time_stamp = meta.time_stamp;
  203. }
  204. if (opts->print_num_rows)
  205. printf("%d", meta.n_rows);
  206. if (opts->print_frame_rate || opts->print_num_rows)
  207. printf("\n");
  208. if (opts->superimpose)
  209. superimpose_on_top (pixels, orig, opts->superimpose);
  210. if (!opts->dry_run)
  211. fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
  212. }
  213. else if (error != EIO) {
  214. fprintf(stderr, "Failed to decode frame %i\n", n_frames);
  215. if (opts->cont) {
  216. /* Save the frame even though we know it is corrupted */
  217. if (!opts->dry_run)
  218. fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
  219. }
  220. else
  221. break;
  222. }
  223. }
  224. if (!opts->dry_run)
  225. fclose(fp);
  226. if (opts->verbose) {
  227. mtime = timer->seconds * 1000.0 + timer->useconds / 1000.0;
  228. printf("Decoded %i frames in %.5fms\n", n_frames, mtime);
  229. }
  230. free(pixels);
  231. free(buffer);
  232. timer_destroy (timer);
  233. ufo_decoder_free(decoder);
  234. return error == EIO ? 0 : error;
  235. }
  236. int main(int argc, char const* argv[])
  237. {
  238. int getopt_ret, index;
  239. enum {
  240. SUPERIMPOSE = 's',
  241. CLEAR_FRAME = 'c',
  242. DRY_RUN = 'd',
  243. FRAME_RATE = 'f',
  244. HELP = 'h',
  245. SET_NUM_ROWS = 'r',
  246. VERBOSE = 'v',
  247. CONTINUE,
  248. NUM_ROWS
  249. };
  250. static struct option long_options[] = {
  251. { "num-rows", required_argument, 0, SET_NUM_ROWS },
  252. { "clear-frame", no_argument, 0, CLEAR_FRAME },
  253. { "verbose", no_argument, 0, VERBOSE },
  254. { "help", no_argument, 0, HELP },
  255. { "dry-run", no_argument, 0, DRY_RUN },
  256. { "print-frame-rate", no_argument, 0, FRAME_RATE },
  257. { "continue", no_argument, 0, CONTINUE },
  258. { "print-num-rows", no_argument, 0, NUM_ROWS },
  259. { "superimpose", required_argument, 0, SUPERIMPOSE },
  260. { 0, 0, 0, 0 }
  261. };
  262. static Options opts = {
  263. .rows = 1088,
  264. .verbose = 0,
  265. .dry_run = 0,
  266. .clear_frame = 0,
  267. .print_frame_rate = 0,
  268. .print_num_rows = 0,
  269. .cont = 0,
  270. .superimpose = 0
  271. };
  272. while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:s:cvhdf", long_options, &index)) != -1) {
  273. switch (getopt_ret) {
  274. case SET_NUM_ROWS:
  275. opts.rows = atoi(optarg);
  276. break;
  277. case CLEAR_FRAME:
  278. opts.clear_frame = 1;
  279. break;
  280. case VERBOSE:
  281. opts.verbose = 1;
  282. break;
  283. case HELP:
  284. usage();
  285. return 0;
  286. case DRY_RUN:
  287. opts.dry_run = 1;
  288. break;
  289. case FRAME_RATE:
  290. opts.print_frame_rate = 1;
  291. break;
  292. case CONTINUE:
  293. opts.cont = 1;
  294. break;
  295. case NUM_ROWS:
  296. opts.print_num_rows = 1;
  297. case SUPERIMPOSE:
  298. opts.superimpose = atoi(optarg);
  299. break;
  300. default:
  301. break;
  302. }
  303. }
  304. if (opts.clear_frame && opts.superimpose) {
  305. fprintf(stderr, "Error: --clear-frame and --superimpose are mutual exclusive\n");
  306. return 1;
  307. }
  308. if (optind == argc) {
  309. printf("ipedec: no input files\n");
  310. return 1;
  311. }
  312. while (optind < argc) {
  313. int errcode = process_file(argv[optind++], &opts);
  314. if (errcode != 0)
  315. return errcode;
  316. }
  317. return 0;
  318. }