/alps/ufodecode

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/ufodecode
4 by Matthias Vogelgesang
Make ipedec a lib and executable
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
12 by Matthias Vogelgesang
Fix: wrong order of pixels when using SSE
4
#include <string.h>
4 by Matthias Vogelgesang
Make ipedec a lib and executable
5
#include <unistd.h>
21 by Matthias Vogelgesang
Use getopt to eat program options
6
#include <errno.h>
4 by Matthias Vogelgesang
Make ipedec a lib and executable
7
#include <sys/time.h>
21 by Matthias Vogelgesang
Use getopt to eat program options
8
#include <getopt.h>
9 by Matthias Vogelgesang
Rename to `ufodecode`
9
#include <ufodecode.h>
4 by Matthias Vogelgesang
Make ipedec a lib and executable
10
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
11
typedef struct {
12
    int clear_frame;
13
    int dry_run;
14
    int verbose;
15
    int rows;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
16
    int print_frame_rate;
17
    int print_num_rows;
39.1.10 by Matthias Vogelgesang
Add --continue flag
18
    int cont;
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
19
    int superimpose;
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
20
} Options;
21
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
22
static int
23
read_raw_file(const char *filename, char **buffer, size_t *length)
4 by Matthias Vogelgesang
Make ipedec a lib and executable
24
{
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
25
    FILE *fp = fopen(filename, "rb");
4 by Matthias Vogelgesang
Make ipedec a lib and executable
26
    if (fp == NULL)
27
        return ENOENT;
28
29
    fseek(fp, 0, SEEK_END);
30
    *length = ftell(fp);
31
    rewind(fp);
32
33
    *buffer = (char *) malloc(*length);
26 by Matthias Vogelgesang
Fix wrong free
34
4 by Matthias Vogelgesang
Make ipedec a lib and executable
35
    if (*buffer == NULL) {
36
        fclose(fp);
37
        return ENOMEM;
38
    }
39
40
    size_t buffer_length = fread(*buffer, 1, *length, fp);
41
    fclose(fp);
42
    if (buffer_length != *length) {
26 by Matthias Vogelgesang
Fix wrong free
43
        free(*buffer);
4 by Matthias Vogelgesang
Make ipedec a lib and executable
44
        return ERANGE;
45
    }
46
    return 0;
47
}
48
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
49
static void
50
usage(void)
22 by Matthias Vogelgesang
Add usage and issue message if no input
51
{
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
52
    printf("usage: ipedec [OPTION]... FILE [FILE ...]\n\
23 by Matthias Vogelgesang
Extend usage
53
Options:\n\
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
54
  -h, --help                Show this help message and exit\n\
55
  -v, --verbose             Print additional information on STDOUT\n\
56
  -r, --num-rows=N          N rows that are contained in the file\n\
57
  -c, --clear-frame         Clear the frame for each iteration\n\
58
  -d, --dry-run             Do not save the frames\n\
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
59
  -s, --superimpose=C       Superimpose frames on top of the first with color C as borders\n\
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
60
  -f, --print-frame-rate    Print frame rate on STDOUT\n\
39.1.10 by Matthias Vogelgesang
Add --continue flag
61
      --print-num-rows      Print number of rows on STDOUT\n\
62
      --continue            Continue decoding frames even when errors occur\n");
22 by Matthias Vogelgesang
Add usage and issue message if no input
63
}
64
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
65
static void
66
print_meta_data (UfoDecoderMeta *meta)
67
{
68
    printf("  frame_number    = %i\n", meta->frame_number);
69
    printf("  time_stamp      = %i\n", meta->time_stamp);
40 by Suren A. Chilingaryan
Read output_mode and adc_resolution from frame header
70
    printf("  output_mode     = %i\n", meta->output_mode);
71
    printf("  adc_resolution  = %i\n", meta->adc_resolution);
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
72
    printf("  n_rows          = %i\n", meta->n_rows);
73
    printf("  n_skipped_rows  = %i\n", meta->n_skipped_rows);
74
75
    printf("  status1\n");
76
    printf("    fsm_master_readout = %i\n", meta->status1.desc.fsm_master_readout);
77
    printf("    fsm_daq         = %i\n", meta->status1.desc.fsm_daq);
78
    printf("    pixel_full      = %i\n", meta->status1.desc.pixel_full);
79
    printf("    control_lock    = %i\n", meta->status1.desc.control_lock);
80
    printf("    data_lock       = %i\n", meta->status1.desc.data_lock);
81
82
    printf("  status2\n");
83
    printf("    end_of_frames   = %i\n", meta->status2.desc.end_of_frames);
84
    printf("    busy_or         = %i\n", meta->status2.desc.busy_or);
85
    printf("    busy_ddr        = %i\n", meta->status2.desc.busy_ddr);
86
    printf("    busy_interl     = %i\n", meta->status2.desc.busy_interl);
87
    printf("    error_status    = %i\n", meta->status2.desc.error_status);
88
    printf("    data_fifo_read_count = %i\n", meta->status2.desc.data_fifo_read_count);
89
    printf("    data_fifo_full       = %i\n", meta->status2.desc.data_fifo_full);
90
    printf("    data_fifo_empty      = %i\n", meta->status2.desc.data_fifo_empty);
91
    printf("    ddr_fifo_write_count = %i\n", meta->status2.desc.ddr_fifo_write_count);
92
    printf("    ddr_fifo_full        = %i\n", meta->status2.desc.ddr_fifo_full);
93
    printf("    ddr_fifo_empty       = %i\n", meta->status2.desc.ddr_fifo_empty);
94
95
    printf("  status3\n");
96
    printf("    row_counter     = %i\n", meta->status3.desc.row_counter);
97
    printf("    pixel_counter   = %i\n", meta->status3.desc.pixel_counter);
98
    printf("    ddr_read        = %i\n", meta->status3.desc.ddr_read);
99
    printf("    ddr_write       = %i\n", meta->status3.desc.ddr_write);
100
    printf("    ddr_arbiter     = %i\n", meta->status3.desc.ddr_arbiter);
101
    printf("\n");
102
}
103
104
typedef struct {
105
    struct timeval  start;
106
    long            seconds;
107
    long            useconds;
108
} Timer;
109
110
static Timer *
111
timer_new (void)
112
{
113
    Timer *t = (Timer *) malloc (sizeof (Timer));
114
    t->seconds = t->useconds = 0L;
115
    return t;
116
}
117
118
static void
119
timer_destroy (Timer *t)
120
{
121
    free (t);
122
}
123
124
static void
125
timer_start (Timer *t)
126
{
127
    gettimeofday(&t->start, NULL);
128
}
129
130
static void
131
timer_stop (Timer *t)
132
{
133
    struct timeval end;
134
135
    gettimeofday(&end, NULL);
136
    t->seconds += end.tv_sec - t->start.tv_sec;
137
    t->useconds += end.tv_usec - t->start.tv_usec;
138
}
139
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
140
static void
141
superimpose_on_top (uint16_t *top, uint16_t *bottom, uint16_t color)
142
{
143
    int x, y;
144
    int in_void = top[0] == 0;
145
146
    for (y = 0; y < 1088; y++) {
147
        int offset = y * 2048;
148
149
        if ((in_void && top[offset] != 0) ||
150
            (!in_void && top[offset] == 0)) {
151
            in_void = 1 - in_void;
152
153
            for (x = 0; x < 2048; x++)
154
                top[offset++] = color;
155
        } 
156
        else {
157
            for (x = 0; x < 2048; x++, offset++) {
158
                if (top[offset] == 0) 
159
                    top[offset] = bottom[offset];
160
            }
161
        }
162
    }
163
}
164
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
165
static int
166
process_file(const char *filename, Options *opts)
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
167
{
168
    UfoDecoder      *decoder;
169
    UfoDecoderMeta   meta = {0};
170
    Timer           *timer;
171
    char            *buffer;
172
    size_t           num_bytes;
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
173
    size_t           frame_size;
174
    uint16_t        *orig;
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
175
    uint16_t        *pixels;
176
    uint32_t         time_stamp, old_time_stamp;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
177
    int              n_frames;
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
178
    int              error = 0;
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
179
    FILE            *fp;
180
    char             output_name[256];
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
181
    float            mtime;
182
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
183
    frame_size = 2048 * 1088 * sizeof(uint16_t);
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
184
    error = read_raw_file(filename, &buffer, &num_bytes);
21 by Matthias Vogelgesang
Use getopt to eat program options
185
186
    if (error) {
24 by Matthias Vogelgesang
Decode frames after encountering corrupted ones
187
        fprintf(stderr, "Error reading %s: %s\n", filename, strerror(error));
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
188
        return error;
21 by Matthias Vogelgesang
Use getopt to eat program options
189
    }
190
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
191
    decoder = ufo_decoder_new(opts->rows, 2048, (uint32_t *) buffer, num_bytes);
4 by Matthias Vogelgesang
Make ipedec a lib and executable
192
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
193
    if (decoder == NULL) {
21 by Matthias Vogelgesang
Use getopt to eat program options
194
        fprintf(stderr, "Failed to initialize decoder\n");
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
195
        return 1;
11.1.3 by Suren A. Chilingaryan
Adjust ipedec as well
196
    }
197
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
198
    if (!opts->dry_run) {
199
        snprintf(output_name, 256, "%s.raw", filename);
200
        fp = fopen(output_name, "wb");
21 by Matthias Vogelgesang
Use getopt to eat program options
201
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
202
        if (!fp) {
203
            fprintf(stderr, "Failed to open file for writing\n");
204
            return 1;
205
        }
11.1.3 by Suren A. Chilingaryan
Adjust ipedec as well
206
    }
4 by Matthias Vogelgesang
Make ipedec a lib and executable
207
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
208
    if (opts->superimpose)
209
        orig = (uint16_t *) malloc(frame_size);
210
211
    pixels = (uint16_t *) malloc(frame_size);
212
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
213
    timer = timer_new ();
214
    n_frames = 0;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
215
    old_time_stamp = 0;
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
216
217
    while (error != EIO) {
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
218
        if (opts->clear_frame || opts->superimpose)
219
            memset(pixels, 0, frame_size);
21 by Matthias Vogelgesang
Use getopt to eat program options
220
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
221
        timer_start (timer);
222
        error = ufo_decoder_get_next_frame(decoder, &pixels, &meta);
223
        timer_stop (timer);
39.1.10 by Matthias Vogelgesang
Add --continue flag
224
        n_frames++;
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
225
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
226
        if (opts->superimpose && n_frames == 1)
227
            memcpy (orig, pixels, frame_size);
228
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
229
        if (!error) {
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
230
            if (opts->verbose) {
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
231
                printf("Status for frame %i\n", n_frames);
232
                print_meta_data (&meta);
233
            }
234
39.1.5 by Matthias Vogelgesang
Add --print-num-rows and fix debug output
235
            if (opts->print_frame_rate) {
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
236
                uint32_t diff = 80 * (meta.time_stamp - old_time_stamp);
237
39.1.5 by Matthias Vogelgesang
Add --print-num-rows and fix debug output
238
                printf("%-6d", 1000000000 / diff);
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
239
                old_time_stamp = meta.time_stamp;
240
            }
241
39.1.5 by Matthias Vogelgesang
Add --print-num-rows and fix debug output
242
            if (opts->print_num_rows)
243
                printf("%d", meta.n_rows); 
244
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
245
            if (opts->print_frame_rate || opts->print_num_rows)
246
                printf("\n");
247
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
248
            if (opts->superimpose)
249
                superimpose_on_top (pixels, orig, opts->superimpose);
250
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
251
            if (!opts->dry_run)
252
                fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
253
        }
254
        else if (error != EIO) {
255
            fprintf(stderr, "Failed to decode frame %i\n", n_frames);
39.1.10 by Matthias Vogelgesang
Add --continue flag
256
257
            if (opts->cont) {
258
                /* Save the frame even though we know it is corrupted */
259
                if (!opts->dry_run)
260
                    fwrite(pixels, sizeof(uint16_t), 2048 * 1088, fp);
261
            }
262
            else
263
                break;
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
264
        }
4 by Matthias Vogelgesang
Make ipedec a lib and executable
265
    }
21 by Matthias Vogelgesang
Use getopt to eat program options
266
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
267
    if (!opts->dry_run)
268
        fclose(fp);
4 by Matthias Vogelgesang
Make ipedec a lib and executable
269
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
270
    if (opts->verbose) {
271
        mtime = timer->seconds * 1000.0 + timer->useconds / 1000.0;
272
        printf("Decoded %i frames in %.5fms\n", n_frames, mtime);
273
    }
4 by Matthias Vogelgesang
Make ipedec a lib and executable
274
275
    free(pixels);
32 by Matthias Vogelgesang
Commit version 0.2 of libufodecode
276
    free(buffer);
277
    timer_destroy (timer);
9 by Matthias Vogelgesang
Rename to `ufodecode`
278
    ufo_decoder_free(decoder);
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
279
280
    return error == EIO ? 0 : error;
21 by Matthias Vogelgesang
Use getopt to eat program options
281
}
282
283
int main(int argc, char const* argv[])
284
{
285
    int getopt_ret, index;
286
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
287
    enum {
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
288
        SUPERIMPOSE  = 's',
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
289
        CLEAR_FRAME  = 'c',
290
        DRY_RUN      = 'd',
291
        FRAME_RATE   = 'f',
292
        HELP         = 'h',
293
        SET_NUM_ROWS = 'r', 
294
        VERBOSE      = 'v',
39.1.10 by Matthias Vogelgesang
Add --continue flag
295
        CONTINUE,
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
296
        NUM_ROWS
297
    };
298
21 by Matthias Vogelgesang
Use getopt to eat program options
299
    static struct option long_options[] = {
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
300
        { "num-rows",           required_argument, 0, SET_NUM_ROWS },
301
        { "clear-frame",        no_argument, 0, CLEAR_FRAME },
302
        { "verbose",            no_argument, 0, VERBOSE },
303
        { "help",               no_argument, 0, HELP },
304
        { "dry-run",            no_argument, 0, DRY_RUN },
305
        { "print-frame-rate",   no_argument, 0, FRAME_RATE },
39.1.10 by Matthias Vogelgesang
Add --continue flag
306
        { "continue",           no_argument, 0, CONTINUE },
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
307
        { "print-num-rows",     no_argument, 0, NUM_ROWS },
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
308
        { "superimpose",        required_argument, 0, SUPERIMPOSE },
21 by Matthias Vogelgesang
Use getopt to eat program options
309
        { 0, 0, 0, 0 }
310
    };
311
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
312
    static Options opts = {
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
313
        .rows = 1088,
314
        .verbose = 0,
315
        .dry_run = 0,
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
316
        .clear_frame = 0,
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
317
        .print_frame_rate = 0,
39.1.10 by Matthias Vogelgesang
Add --continue flag
318
        .print_num_rows = 0,
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
319
        .cont = 0,
320
        .superimpose = 0
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
321
    };
21 by Matthias Vogelgesang
Use getopt to eat program options
322
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
323
    while ((getopt_ret = getopt_long(argc, (char *const *) argv, "r:s:cvhdf", long_options, &index)) != -1) {
21 by Matthias Vogelgesang
Use getopt to eat program options
324
        switch (getopt_ret) {
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
325
            case SET_NUM_ROWS:
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
326
                opts.rows = atoi(optarg);
21 by Matthias Vogelgesang
Use getopt to eat program options
327
                break;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
328
            case CLEAR_FRAME:
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
329
                opts.clear_frame = 1;
21 by Matthias Vogelgesang
Use getopt to eat program options
330
                break;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
331
            case VERBOSE:
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
332
                opts.verbose = 1;
28 by Matthias Vogelgesang
Add verbosity flag to output frequency and frame
333
                break;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
334
            case HELP:
22 by Matthias Vogelgesang
Add usage and issue message if no input
335
                usage();
336
                return 0;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
337
            case DRY_RUN:
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
338
                opts.dry_run = 1;
339
                break;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
340
            case FRAME_RATE:
341
                opts.print_frame_rate = 1;
342
                break;
39.1.10 by Matthias Vogelgesang
Add --continue flag
343
            case CONTINUE:
344
                opts.cont = 1;
345
                break;
39.1.4 by Matthias Vogelgesang
Add -f and --print-frame-rate option
346
            case NUM_ROWS:
347
                opts.print_num_rows = 1;
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
348
            case SUPERIMPOSE:
349
                opts.superimpose = atoi(optarg);
350
                break;
21 by Matthias Vogelgesang
Use getopt to eat program options
351
            default:
352
                break;
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
353
        }
21 by Matthias Vogelgesang
Use getopt to eat program options
354
    }
355
39.1.12 by Matthias Vogelgesang
Add -s/--superimpose flag to color borders
356
    if (opts.clear_frame && opts.superimpose) {
357
        fprintf(stderr, "Error: --clear-frame and --superimpose are mutual exclusive\n");
358
        return 1;
359
    }
360
37 by Matthias Vogelgesang
Issue `no input files` also with options set
361
    if (optind == argc) {
362
        printf("ipedec: no input files\n");
363
        return 1;
364
    }
365
39.1.2 by Matthias Vogelgesang
Return errcode != 0 if frame could not be decoded
366
    while (optind < argc) {
367
        int errcode = process_file(argv[optind++], &opts);
368
369
        if (errcode != 0)
370
            return errcode;
371
    }
4 by Matthias Vogelgesang
Make ipedec a lib and executable
372
373
    return 0;
374
}
375