1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#define STB_IMAGE_IMPLEMENTATION
#include "io/stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "io/stb/stb_image_write.h"
#include "libanalog/ntsc.h"
#include <stdio.h>
void print_usage(const char* self_name)
{
fprintf(stdout, "Usage: %s <MODE> <INPUT> <OUTPUT>\n", self_name);
fprintf(stdout, "<MODE>: e - encode, or d - decode\n");
fprintf(stdout, "<INPUT>: Path to input file (bmp, jpeg, png)\n");
fprintf(stdout, "<OUTPUT>: Path to output file, file will be saved in bmp format\n\n");
fprintf(stdout, "Example: %s e ~/lena.jpg ~/lena_coded.bmp\n", self_name);
fprintf(stdout, " %s d ~/lena_coded.bmp ~/lena_decoded.bmp\n", self_name);
}
int main(int argc, char** argv)
{
if (argc != 4)
print_usage(argv[0]);
const char* input_file = argv[2];
const char* output_file = argv[3];
const int encode = *argv[1] == 'e';
int width, height, components, out_components;
int line = 0;
int i = 0;
int rv = 1;
unsigned char* input_image = stbi_load(input_file,
&width, &height, &components, encode ? STBI_rgb : STBI_grey);
if (!input_image) {
fprintf(stderr, "Unable to load image\n");
goto exit;
}
// stbi returns component = 3 even for STBI_grey
if ((encode && components != 3) || (!encode && components != 3)) {
fprintf(stderr, "Unexpected image format, components: %d\n", components);
goto exit;
}
out_components = encode ? 1 : 3;
components = encode ? 3 : 1;
ntsc_ctx* ctx = ntsc_create_context(width, encode);
if (!ctx) {
fprintf(stderr, "Unable to crete ntsc context\n");
goto exit_free_input_image;
}
unsigned char* output_image = malloc(height * width * out_components);
if (!output_image) {
fprintf(stderr, "Unable to allocate memory for output image\n");
goto exit_free_ctx;
}
float* input_line = malloc(sizeof(float) * width * components);
if (!input_line) {
fprintf(stderr, "Unable to allocate memory\n");
goto exit_free_output_image;
}
float* output_line = malloc(sizeof(float) * width * out_components);
if (!output_line) {
fprintf(stderr, "Unable to allocate memory\n");
goto exit_free_input_line;
}
for (line = 0; line < height; line++) {
for (i = 0; i < width * components; i++) {
input_line[i] = (float)input_image[i + line * width * components] / 255.0f - 0.5;
}
if (encode) {
ntsc_process_encode(input_line, output_line, ctx);
} else {
ntsc_process_decode(input_line, output_line, ctx);
}
for (i = 0; i < width * out_components; i++) {
int t = round((output_line[i] + 0.5) * 255.0f);
output_image[i + line * width * out_components] = t < 0 ? 0 : ((t > 255) ? 255 : t);
}
}
rv = !stbi_write_bmp(output_file, width, height, out_components, output_image);
free(output_line);
exit_free_input_line:
free(input_line);
exit_free_output_image:
free(output_image);
exit_free_ctx:
ntsc_free_context(ctx);
exit_free_input_image:
stbi_image_free(input_image);
exit:
if (rv) {
return 1;
}
return 0;
}
|