123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <getopt.h>
- #include <ufodecode.h>
- typedef struct {
- int clear_frame;
- int dry_run;
- int verbose;
- int rows;
- int print_frame_rate;
- int print_num_rows;
- int cont;
- int superimpose;
- } Options;
- static int
- read_raw_file(const char *filename, char **buffer, size_t *length)
- {
- FILE *fp = fopen(filename, "rb");
- if (fp == NULL)
- return ENOENT;
- fseek(fp, 0, SEEK_END);
- *length = ftell(fp);
- rewind(fp);
- *buffer = (char *) malloc(*length);
- if (*buffer == NULL) {
- fclose(fp);
- return ENOMEM;
- }
- size_t buffer_length = fread(*buffer, 1, *length, fp);
- fclose(fp);
- if (buffer_length != *length) {
- free(*buffer);
- return ERANGE;
- }
- return 0;
- }
- static void
- usage(void)
- {
- printf("usage: ipedec [OPTION]... FILE [FILE ...]\n\
- Options:\n\
- -h, --help Show this help message and exit\n\
- -v, --verbose Print additional information on STDOUT\n\
- -r, --num-rows=N N rows that are contained in the file\n\
- -c, --clear-frame Clear the frame for each iteration\n\
- -d, --dry-run Do not save the frames\n\
- -s, --superimpose=C Superimpose frames on top of the first with color C as borders\n\
- -f, --print-frame-rate Print frame rate on STDOUT\n\
- --print-num-rows Print number of rows on STDOUT\n\
- --continue Continue decoding frames even when errors occur\n");
- }
- static void
- print_meta_data (UfoDecoderMeta *meta)
- {
- printf(" frame_number = %i\n", meta->frame_number);
- printf(" time_stamp = %i\n", meta->time_stamp);
- printf(" output_mode = %i\n", meta->output_mode);
- printf(" adc_resolution = %i\n", meta->adc_resolution);
- printf(" n_rows = %i\n", meta->n_rows);
- printf(" n_skipped_rows = %i\n", meta->n_skipped_rows);
- printf(" status1\n");
- printf(" fsm_master_readout = %i\n", meta->status1.desc.fsm_master_readout);
- printf(" fsm_daq = %i\n", meta->status1.desc.fsm_daq);
- printf(" pixel_full = %i\n", meta->status1.desc.pixel_full);
- printf(" control_lock = %i\n", meta->status1.desc.control_lock);
- printf(" data_lock = %i\n", meta->status1.desc.data_lock);
- printf(" status2\n");
- printf(" end_of_frames = %i\n", meta->status2.desc.end_of_frames);
- printf(" busy_or = %i\n", meta->status2.desc.busy_or);
- printf(" busy_ddr = %i\n", meta->status2.desc.busy_ddr);
- printf(" busy_interl = %i\n", meta->status2.desc.busy_interl);
- printf(" error_status = %i\n", meta->status2.desc.error_status);
- printf(" data_fifo_read_count = %i\n", meta->status2.desc.data_fifo_read_count);
- printf(" data_fifo_full = %i\n", meta->status2.desc.data_fifo_full);
- printf(" data_fifo_empty = %i\n", meta->status2.desc.data_fifo_empty);
- printf(" ddr_fifo_write_count = %i\n", meta->status2.desc.ddr_fifo_write_count);
- printf(" ddr_fifo_full = %i\n", meta->status2.desc.ddr_fifo_full);
- printf(" ddr_fifo_empty = %i\n", meta->status2.desc.ddr_fifo_empty);
- printf(" status3\n");
- printf(" row_counter = %i\n", meta->status3.desc.row_counter);
- printf(" pixel_counter = %i\n", meta->status3.desc.pixel_counter);
- printf(" ddr_read = %i\n", meta->status3.desc.ddr_read);
- printf(" ddr_write = %i\n", meta->status3.desc.ddr_write);
- printf(" ddr_arbiter = %i\n", meta->status3.desc.ddr_arbiter);
- printf("\n");
- }
- typedef struct {
- struct timeval start;
- long seconds;
- long useconds;
- } Timer;
- static Timer *
- timer_new (void)
- {
- Timer *t = (Timer *) malloc (sizeof (Timer));
- t->seconds = t->useconds = 0L;
- return t;
- }
- static void
- timer_destroy (Timer *t)
- {
- free (t);
- }
- static void
- timer_start (Timer *t)
- {
- gettimeofday(&t->start, NULL);
- }
- static void
- timer_stop (Timer *t)
- {
- struct timeval end;
- gettimeofday(&end, NULL);
- t->seconds += end.tv_sec - t->start.tv_sec;
- t->useconds += end.tv_usec - t->start.tv_usec;
- }
- static void
- superimpose_on_top (uint16_t *top, uint16_t *bottom, uint16_t color)
- {
- int x, y;
- int in_void = top[0] == 0;
- for (y = 0; y < 1088; y++) {
- int offset = y * 2048;
- if ((in_void && top[offset] != 0) ||
- (!in_void && top[offset] == 0)) {
- in_void = 1 - in_void;
- for (x = 0; x < 2048; x++)
- top[offset++] = color;
- }
- else {
- for (x = 0; x < 2048; x++, offset++) {
- if (top[offset] == 0)
- top[offset] = bottom[offset];
- }
- }
- }
- }
- static int
- process_file(const char *filename, Options *opts)
- {
- UfoDecoder *decoder;
- UfoDecoderMeta meta = {0};
- Timer *timer;
- char *buffer;
- size_t num_bytes;
- size_t frame_size;
- uint16_t *orig;
- uint16_t *pixels;
- uint32_t time_stamp, old_time_stamp;
- int n_frames;
- int error = 0;
- FILE *fp;
- char output_name[256];
- float mtime;
- frame_size = 2048 * 1088 * sizeof(uint16_t);
- error = read_raw_file(filename, &buffer, &num_bytes);
- if (error) {
- fprintf(stderr, "Error reading %s: %s\n", filename, strerror(error));
- return error;
- }
- decoder = ufo_decoder_new(opts->rows, 2048, (uint32_t *) buffer, num_bytes);
- if (decoder == NULL) {
- fprintf(stderr, "Failed to initialize decoder\n");
- return 1;
- }
- if (!opts->dry_run) {
- snprintf(output_name, 256, "%s.raw", filename);
- fp = fopen(output_name, "wb");
- if (!fp) {
- fprintf(stderr, "Failed to open file for writing\n");
- return 1;
- }
- }
- if (opts->superimpose)
- orig = (uint16_t *) malloc(frame_size);
- pixels = (uint16_t *) malloc(frame_size);
- timer = timer_new ();
- n_frames = 0;
- old_time_stamp = 0;
- while (error != EIO) {
- if (opts->clear_frame || opts->superimpose)
- memset(pixels, 0, frame_size);
- timer_start (timer);
- error = ufo_decoder_get_next_frame(decoder, &pixels, &meta);
- timer_stop (timer);
- n_frames++;
- if (opts->superimpose && n_frames == 1)
- memcpy (orig, pixels, frame_size);
- if (!error) {
- if (opts->verbose) {
- printf("Status for frame %i\n", n_frames);
- print_meta_data (&meta);
- }
- if (opts->print_frame_rate) {
- uint32_t diff = 80 * (meta.time_stamp - old_time_stamp);
- printf("%-6d", 1000000000 / diff);
- old_time_stamp = meta.time_stamp;
- }
- if (opts->print_num_rows)
- printf("%d", meta.n_rows);
- if (opts->print_frame_rate || opts->print_num_rows)
- printf("\n");
- if (opts->superimpose)
- superimpose_on_top (pixels, orig, opts->superimpose);
- if (!opts->dry_run)
- fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
- }
- else if (error != EIO) {
- fprintf(stderr, "Failed to decode frame %i\n", n_frames);
- if (opts->cont) {
- /* Save the frame even though we know it is corrupted */
- if (!opts->dry_run)
- fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
- }
- else
- break;
- }
- }
- if (!opts->dry_run)
- fclose(fp);
- if (opts->verbose) {
- mtime = timer->seconds * 1000.0 + timer->useconds / 1000.0;
- printf("Decoded %i frames in %.5fms\n", n_frames, mtime);
- }
- free(pixels);
- free(buffer);
- timer_destroy (timer);
- ufo_decoder_free(decoder);
- return error == EIO ? 0 : error;
- }
- int main(int argc, char const* argv[])
- {
- int getopt_ret, index;
- enum {
- SUPERIMPOSE = 's',
- CLEAR_FRAME = 'c',
- DRY_RUN = 'd',
- FRAME_RATE = 'f',
- HELP = 'h',
- SET_NUM_ROWS = 'r',
- VERBOSE = 'v',
- CONTINUE,
- NUM_ROWS
- };
- static struct option long_options[] = {
- { "num-rows", required_argument, 0, SET_NUM_ROWS },
- { "clear-frame", no_argument, 0, CLEAR_FRAME },
- { "verbose", no_argument, 0, VERBOSE },
- { "help", no_argument, 0, HELP },
- { "dry-run", no_argument, 0, DRY_RUN },
- { "print-frame-rate", no_argument, 0, FRAME_RATE },
- { "continue", no_argument, 0, CONTINUE },
- { "print-num-rows", no_argument, 0, NUM_ROWS },
- { "superimpose", required_argument, 0, SUPERIMPOSE },
- { 0, 0, 0, 0 }
- };
- static Options opts = {
- .rows = 1088,
- .verbose = 0,
- .dry_run = 0,
- .clear_frame = 0,
- .print_frame_rate = 0,
- .print_num_rows = 0,
- .cont = 0,
- .superimpose = 0
- };
- while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:s:cvhdf", long_options, &index)) != -1) {
- switch (getopt_ret) {
- case SET_NUM_ROWS:
- opts.rows = atoi(optarg);
- break;
- case CLEAR_FRAME:
- opts.clear_frame = 1;
- break;
- case VERBOSE:
- opts.verbose = 1;
- break;
- case HELP:
- usage();
- return 0;
- case DRY_RUN:
- opts.dry_run = 1;
- break;
- case FRAME_RATE:
- opts.print_frame_rate = 1;
- break;
- case CONTINUE:
- opts.cont = 1;
- break;
- case NUM_ROWS:
- opts.print_num_rows = 1;
- case SUPERIMPOSE:
- opts.superimpose = atoi(optarg);
- break;
- default:
- break;
- }
- }
- if (opts.clear_frame && opts.superimpose) {
- fprintf(stderr, "Error: --clear-frame and --superimpose are mutual exclusive\n");
- return 1;
- }
- if (optind == argc) {
- printf("ipedec: no input files\n");
- return 1;
- }
- while (optind < argc) {
- int errcode = process_file(argv[optind++], &opts);
- if (errcode != 0)
- return errcode;
- }
- return 0;
- }
|