|
@@ -16,6 +16,7 @@ typedef struct {
|
|
|
int print_frame_rate;
|
|
|
int print_num_rows;
|
|
|
int cont;
|
|
|
+ int superimpose;
|
|
|
} Options;
|
|
|
|
|
|
static int
|
|
@@ -55,6 +56,7 @@ Options:\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");
|
|
@@ -135,6 +137,31 @@ timer_stop (Timer *t)
|
|
|
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)
|
|
|
{
|
|
@@ -143,6 +170,8 @@ process_file(const char *filename, Options *opts)
|
|
|
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;
|
|
@@ -151,6 +180,7 @@ process_file(const char *filename, Options *opts)
|
|
|
char output_name[256];
|
|
|
float mtime;
|
|
|
|
|
|
+ frame_size = 2048 * 1088 * sizeof(uint16_t);
|
|
|
error = read_raw_file(filename, &buffer, &num_bytes);
|
|
|
|
|
|
if (error) {
|
|
@@ -175,22 +205,28 @@ process_file(const char *filename, Options *opts)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (opts->superimpose)
|
|
|
+ orig = (uint16_t *) malloc(frame_size);
|
|
|
+
|
|
|
+ pixels = (uint16_t *) malloc(frame_size);
|
|
|
+
|
|
|
timer = timer_new ();
|
|
|
- pixels = (uint16_t *) malloc(2048 * 1088 * sizeof(uint16_t));
|
|
|
n_frames = 0;
|
|
|
old_time_stamp = 0;
|
|
|
|
|
|
while (error != EIO) {
|
|
|
- if (opts->clear_frame)
|
|
|
- memset(pixels, 0, 2048 * 1088 * sizeof(uint16_t));
|
|
|
+ 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 (!error) {
|
|
|
+ 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);
|
|
@@ -209,6 +245,9 @@ process_file(const char *filename, Options *opts)
|
|
|
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);
|
|
|
}
|
|
@@ -246,6 +285,7 @@ int main(int argc, char const* argv[])
|
|
|
int getopt_ret, index;
|
|
|
|
|
|
enum {
|
|
|
+ SUPERIMPOSE = 's',
|
|
|
CLEAR_FRAME = 'c',
|
|
|
DRY_RUN = 'd',
|
|
|
FRAME_RATE = 'f',
|
|
@@ -265,6 +305,7 @@ int main(int argc, char const* argv[])
|
|
|
{ "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 }
|
|
|
};
|
|
|
|
|
@@ -275,10 +316,11 @@ int main(int argc, char const* argv[])
|
|
|
.clear_frame = 0,
|
|
|
.print_frame_rate = 0,
|
|
|
.print_num_rows = 0,
|
|
|
- .cont = 0
|
|
|
+ .cont = 0,
|
|
|
+ .superimpose = 0
|
|
|
};
|
|
|
|
|
|
- while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:cvhdf", long_options, &index)) != -1) {
|
|
|
+ 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);
|
|
@@ -303,11 +345,19 @@ int main(int argc, char const* argv[])
|
|
|
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;
|