/alps/ufodecode

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/ufodecode
5 by Matthias Vogelgesang
(Re-)move executable sources
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <stdint.h>
5
#include <errno.h>
6
#include <assert.h>
7
#include <getopt.h>
8
9
#define IPE_DEFAULT_WIDTH 2048
10
11
char *strdup(const char *str)
12
{
13
    int n = strlen(str) + 1;
14
    char *dup = malloc(n);
15
    if (dup)
16
        strcpy(dup, str);
17
    return dup;
18
}
19
20
int process_simple_frame(const uint16_t *frame_in, uint16_t *frame_out, int width, int height)
21
{
22
    const size_t row_size_bytes = width * sizeof(uint16_t);
23
24
    for (int row = 0; row < height; row++) {
25
        /* Copy one line */
26
        memcpy(frame_out, frame_in + row*width, row_size_bytes);
27
        frame_out += width;
28
29
        /* Interpolate between source row and row+1 */ 
30
        for (int x = 0; x < width; x++) {
31
            frame_out[x] = (int) (0.5 * frame_in[row*width + x] + 0.5 * frame_in[(row+1)*width + x]);
32
        }
33
        frame_out += width;
34
    }
35
36
    /* Copy last row */
37
    memcpy(frame_out, frame_in + width * (height - 1), row_size_bytes);
38
    return 0;
39
}
40
41
int weave(const uint16_t *frames_in, uint16_t *frame_out, int width, int height)
42
{
43
    const size_t row_size_bytes = width * sizeof(uint16_t);
44
    const size_t frame_offset = width * height;
45
    for (int row = 0; row < height; row++) {
46
        memcpy(frame_out, frames_in + row*width, row_size_bytes); 
47
        frame_out += width;
48
        memcpy(frame_out, frames_in + frame_offset + row*width, row_size_bytes); 
49
        frame_out += width;
50
    }
51
    return 0;
52
}
53
54
int process_file(const char *filename, int width, int height, int num_lines_skipped)
55
{
56
    FILE *fp = fopen(filename, "rb");
57
    if (fp == NULL) {
58
        return EIO; 
59
    }
60
    fseek(fp, 0, SEEK_END);
61
    const size_t file_size = ftell(fp);
62
    rewind(fp);
63
64
    uint16_t *frame_in_buffer = (uint16_t *) malloc(file_size);
65
    if (frame_in_buffer == NULL) {
66
        fclose(fp);
67
        return ENOMEM;
68
    }
69
70
    size_t buffer_length = fread(frame_in_buffer, 1, file_size, fp);
71
    fclose(fp);
72
    if (buffer_length != file_size) {
73
        free(frame_in_buffer);
74
        return EIO;
75
    }
76
77
    uint16_t *frame_out_buffer = (uint16_t *) malloc(file_size * 2);
78
    if (frame_out_buffer == NULL) {
79
        fclose(fp);
80
        return ENOMEM;
81
    }
82
83
    const int num_frames = file_size / (width * height * sizeof(uint16_t));
84
    printf("de-interlacing %i frames...\n", num_frames);
85
    /*
86
    for (int frame = 0; frame < num_frames; frame++) {
87
        process_simple_frame(
88
                frame_in_buffer + frame * (width * height),
89
                frame_out_buffer + frame * (width * height * 2),
90
                width, height);
91
    }
92
    */
93
    for (int frame = 0; frame < num_frames-1; frame++) {
94
        weave(frame_in_buffer + frame * (width * height),
95
              frame_out_buffer + frame * (width * height * 2),
96
              width, height);
97
    }
98
99
    fp = fopen("result.raw", "wb");
100
    fwrite(frame_out_buffer, 1, file_size * 2, fp);
101
    fclose(fp);
102
103
    free(frame_in_buffer);
104
    free(frame_out_buffer);
105
    return 0;
106
}
107
108
int main(int argc, char const* argv[])
109
{
110
    static struct option long_options[] = {
111
        { "width", 1, 0, 'w' },
112
        { "interlaced-height", 1, 0, 'i' },
113
        { "target-height", 1, 0, 't' },
114
        { "file", 1, 0, 'f' },
115
        { NULL, 0, NULL, 0 }
116
    }; 
117
118
    int c, option_index = 0, errnum;
119
    int width = IPE_DEFAULT_WIDTH;
120
    int interlaced_height = -1;
121
    int target_height = -1;
122
    char *file_name = NULL;
123
    char *end;
124
125
    while ((c = getopt_long(argc, (char *const *) argv, "w:i:t:f:", long_options, &option_index)) != -1) {
126
        switch (c) {
127
            case 'w': 
128
                width = (int) strtol(optarg, &end, 10);
129
                break;
130
            case 'i':
131
                interlaced_height = (int) strtol(optarg, &end, 10);
132
                break;
133
            case 't':
134
                target_height = (int) strtol(optarg, &end, 10);
135
                break;
136
            case 'f':
137
                file_name = strdup( (char *) optarg);
138
                break;
139
        } 
140
    }
141
142
    if (interlaced_height == -1 || file_name == NULL) {
143
        printf("Usage: deinterlace --interlaced-height=[number] --target-height=[number] --file=[name]\n");
144
        exit(EXIT_FAILURE);
145
    }
146
147
    if (target_height == -1)
148
        target_height = interlaced_height * 2;
149
150
    if ((errnum = process_file(file_name, width, interlaced_height, (target_height / interlaced_height) - 1)))
151
        printf("Error occured: %s\n", strerror(errnum));
152
153
    free(file_name);
154
    return 0;
155
}
156