diff options
-rw-r--r-- | src/ufodecode.c | 146 | ||||
-rw-r--r-- | test/ipedec.c | 103 |
2 files changed, 125 insertions, 124 deletions
diff --git a/src/ufodecode.c b/src/ufodecode.c index 6f3f299..072e409 100644 --- a/src/ufodecode.c +++ b/src/ufodecode.c @@ -398,18 +398,18 @@ static int ufo_decode_frame_channels_v5(UfoDecoder *decoder, uint16_t *pixel_buffer, uint32_t *raw, - size_t num_words, size_t num_rows, size_t *offset, uint8_t output_mode) { payload_header_v5 *header; size_t base = 0, index = 0; - int off = 0; header = (payload_header_v5 *) &raw[base]; if (output_mode == IPECAMERA_MODE_4_CHAN_IO) { + size_t off = 0; + while (raw[base] != 0xAAAAAAA) { header = (payload_header_v5 *) &raw[base]; index = header->row_number * IPECAMERA_WIDTH + header->pixel_number; @@ -433,33 +433,12 @@ ufo_decode_frame_channels_v5(UfoDecoder *decoder, base += 6; } } - else { /*if (output_mode == IPECAMERA_MODE_16_CHAN_IO)*/ + else { while (raw[base] != 0xAAAAAAA) { header = (payload_header_v5 *) &raw[base]; index = header->row_number * IPECAMERA_WIDTH + header->pixel_number; /* Skip header + two zero-filled words */ - /* - base += 3; - pixel_buffer[index + 15*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 22); - pixel_buffer[index + 13*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 12); - pixel_buffer[index + 14*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 2); - pixel_buffer[index + 12*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3 & raw[base]) << 8) | (0x3ff & (raw[base+1] >> 24)); - pixel_buffer[index + 10*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 14); - pixel_buffer[index + 8*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 4); - pixel_buffer[index + 11*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xf & raw[base+1]) << 6) | (0x3ff & (raw[base+2] >> 26)); - pixel_buffer[index + 7*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 16); - pixel_buffer[index + 9*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 6); - pixel_buffer[index + 6*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3f & raw[base+2]) << 4) | (0x3ff & (raw[base+3] >> 28)); - pixel_buffer[index + 5*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 18); - pixel_buffer[index + 2*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 8); - pixel_buffer[index + 4*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xff & raw[base+3]) << 2) | (0x3ff & (raw[base+4] >> 30)); - pixel_buffer[index + 3*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 20); - pixel_buffer[index + 0*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 10); - pixel_buffer[index + 1*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+4]; - base += 5; - */ - base += 2; if (header->magic != 0xc0) { @@ -480,22 +459,15 @@ ufo_decode_frame_channels_v5(UfoDecoder *decoder, pixel_buffer[index + 0*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+5] >> 12); pixel_buffer[index + 1*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+5]; } - else { - off++; - - if (header->magic == 0xc0) - off = 0; - } base += 6; - } } - *offset = base; return 0; } + /** * \brief Deinterlace by interpolating between two rows * @@ -584,78 +556,78 @@ size_t ufo_decoder_decode_frame(UfoDecoder *decoder, CHECK_VALUE(raw[pos++], 0x55555555); switch (version) { - case 0: - CHECK_VALUE(raw[pos++], 0x56666666); - CHECK_VALUE(raw[pos] >> 28, 0x5); - meta->frame_number = raw[pos++] & 0xFFFFFFF; - CHECK_VALUE(raw[pos] >> 28, 0x5); - meta->time_stamp = raw[pos++] & 0xFFFFFFF; - break; - - case 4: - case 5: - CHECK_VALUE(raw[pos] >> 28, 0x5); - meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF; - meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F; - meta->n_rows = rows_per_frame = raw[pos] & 0x7FF; - pos++; + case 0: + CHECK_VALUE(raw[pos++], 0x56666666); + CHECK_VALUE(raw[pos] >> 28, 0x5); + meta->frame_number = raw[pos++] & 0xFFFFFFF; + CHECK_VALUE(raw[pos] >> 28, 0x5); + meta->time_stamp = raw[pos++] & 0xFFFFFFF; + break; + + case 4: + case 5: + CHECK_VALUE(raw[pos] >> 28, 0x5); + meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF; + meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F; + meta->n_rows = rows_per_frame = raw[pos] & 0x7FF; + pos++; - meta->frame_number = raw[pos++] & 0x1FFFFFF; - CHECK_VALUE(raw[pos] >> 28, 0x5); - meta->time_stamp = raw[pos] & 0xFFFFFF; - meta->output_mode = (raw[pos] >> 24) & 0x3; - meta->adc_resolution = (raw[pos] >> 26) & 0x3; - pos++; + meta->frame_number = raw[pos++] & 0x1FFFFFF; + CHECK_VALUE(raw[pos] >> 28, 0x5); + meta->time_stamp = raw[pos] & 0xFFFFFF; + meta->output_mode = (raw[pos] >> 24) & 0x3; + meta->adc_resolution = (raw[pos] >> 26) & 0x3; + pos++; - if ((meta->output_mode != IPECAMERA_MODE_4_CHAN_IO)&&(meta->output_mode != IPECAMERA_MODE_16_CHAN_IO)) { + if ((meta->output_mode != IPECAMERA_MODE_4_CHAN_IO)&&(meta->output_mode != IPECAMERA_MODE_16_CHAN_IO)) { #ifdef DEBUG - fprintf(stderr, "Output mode 0x%lx is not supported\n", meta->output_mode); + fprintf(stderr, "Output mode 0x%lx is not supported\n", meta->output_mode); #endif - return EILSEQ; - } - break; + return EILSEQ; + } + break; - default: - fprintf(stderr, "Unsupported data format detected\n"); - return 0; + default: + fprintf(stderr, "Unsupported data format detected\n"); + return 0; } if (err) return 0; #else switch (version) { - case 0: - meta->frame_number = raw[pos + 6] & 0xFFFFFFF; - meta->time_stamp = raw[pos + 7] & 0xFFFFFFF; - break; - case 4: - case 5: - meta->frame_number = raw[pos + 6] & 0x1FFFFFF; - meta->time_stamp = raw[pos + 7] & 0xFFFFFF; - meta->output_mode = (raw[pos + 7] >> 24) & 0x3; - meta->adc_resolution = (raw[pos + 7] >> 26) & 0x3; - - break; - default: - fprintf(stderr, "Unsupported data format detected\n"); - return 0; + case 0: + meta->frame_number = raw[pos + 6] & 0xFFFFFFF; + meta->time_stamp = raw[pos + 7] & 0xFFFFFFF; + break; + case 4: + case 5: + meta->frame_number = raw[pos + 6] & 0x1FFFFFF; + meta->time_stamp = raw[pos + 7] & 0xFFFFFF; + meta->output_mode = (raw[pos + 7] >> 24) & 0x3; + meta->adc_resolution = (raw[pos + 7] >> 26) & 0x3; + + break; + default: + fprintf(stderr, "Unsupported data format detected\n"); + return 0; } pos += 8; #endif switch (version) { - case 0: - err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance); - break; - case 4: - err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance); - break; - case 5: - err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance, meta->output_mode); - break; - default: - break; + case 0: + err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance); + break; + case 4: + err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance); + break; + case 5: + err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, rows_per_frame, &advance, meta->output_mode); + break; + default: + break; } if (err) diff --git a/test/ipedec.c b/test/ipedec.c index c9eceb3..af0b304 100644 --- a/test/ipedec.c +++ b/test/ipedec.c @@ -8,10 +8,17 @@ #include <getopt.h> #include <ufodecode.h> +typedef struct { + int clear_frame; + int dry_run; + int verbose; + int rows; +} Options; + static int read_raw_file(const char *filename, char **buffer, size_t *length) { - FILE *fp = fopen(filename, "rb"); + FILE *fp = fopen(filename, "rb"); if (fp == NULL) return ENOENT; @@ -38,12 +45,13 @@ read_raw_file(const char *filename, char **buffer, size_t *length) static void usage(void) { - printf("usage: ipedec [--num-rows=ROWS] [--clear-frame] FILE [FILE ...]\n\ + 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"); + -c, --clear-frame Clear the frame for each iteration\n\ + -d, --dry-run Do not save the frames\n"); } static void @@ -121,41 +129,44 @@ timer_stop (Timer *t) t->useconds += end.tv_usec - t->start.tv_usec; } -static void -process_file(const char *filename, int rows, int clear_frame, int verbose) +static int +process_file(const char *filename, Options *opts) { UfoDecoder *decoder; UfoDecoderMeta meta = {0}; Timer *timer; char *buffer; size_t num_bytes; - int error; uint16_t *pixels; uint32_t time_stamp, old_time_stamp; int n_frames = 0; + int error = 0; FILE *fp; char output_name[256]; - + float mtime; + error = read_raw_file(filename, &buffer, &num_bytes); if (error) { fprintf(stderr, "Error reading %s: %s\n", filename, strerror(error)); - return; + return error; } - decoder = ufo_decoder_new(rows, 2048, (uint32_t *) buffer, num_bytes); + decoder = ufo_decoder_new(opts->rows, 2048, (uint32_t *) buffer, num_bytes); if (decoder == NULL) { fprintf(stderr, "Failed to initialize decoder\n"); - return; + return 1; } - snprintf(output_name, 256, "%s.raw", filename); - fp = fopen(output_name, "wb"); + 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; + if (!fp) { + fprintf(stderr, "Failed to open file for writing\n"); + return 1; + } } timer = timer_new (); @@ -163,7 +174,7 @@ process_file(const char *filename, int rows, int clear_frame, int verbose) n_frames = 0; while (error != EIO) { - if (clear_frame) + if (opts->clear_frame) memset(pixels, 0, 2048 * 1088 * sizeof(uint16_t)); timer_start (timer); @@ -171,27 +182,34 @@ process_file(const char *filename, int rows, int clear_frame, int verbose) timer_stop (timer); if (!error) { - if (verbose) { + if (opts->verbose) { printf("Status for frame %i\n", n_frames); print_meta_data (&meta); } n_frames++; - fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp); + + 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); + break; } - else if (error != EIO) - fprintf(stderr, "Failed to decode frame %i\n", n_frames); } - fclose(fp); + if (!opts->dry_run) + fclose(fp); - float mtime = timer->seconds * 1000.0 + timer->useconds / 1000.0; + 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[]) @@ -199,34 +217,41 @@ int main(int argc, char const* argv[]) int getopt_ret, index; static struct option long_options[] = { - { "num-rows", required_argument, 0, 'r' }, - { "clear-frame", no_argument, 0, 'c' }, - { "verbose", no_argument, 0, 'v' }, - { "help", no_argument, 0, 'h' }, + { "num-rows", required_argument, 0, 'r' }, + { "clear-frame", no_argument, 0, 'c' }, + { "verbose", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, + { "dry-run", no_argument, 0, 'd' }, { 0, 0, 0, 0 } }; - int clear_frame = 0; - int verbose = 0; - int rows = 1088; + static Options opts = { + .clear_frame = 0, + .dry_run = 0, + .verbose = 0, + .rows = 1088 + }; - while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:cvh", long_options, &index)) != -1) { + while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:cvhd", long_options, &index)) != -1) { switch (getopt_ret) { - case 'r': - rows = atoi(optarg); + case 'r': + opts.rows = atoi(optarg); break; case 'c': - clear_frame = 1; + opts.clear_frame = 1; break; case 'v': - verbose = 1; + opts.verbose = 1; break; case 'h': usage(); return 0; + case 'd': + opts.dry_run = 1; + break; default: break; - } + } } if (optind == argc) { @@ -234,8 +259,12 @@ int main(int argc, char const* argv[]) return 1; } - while (optind < argc) - process_file(argv[optind++], rows, clear_frame, verbose); + while (optind < argc) { + int errcode = process_file(argv[optind++], &opts); + + if (errcode != 0) + return errcode; + } return 0; } |