Mercurial > hg > wm
annotate Meerwald/cmp_pgm.c @ 22:d8551fb39a5e default tip
Added tag v0.6 for changeset 1c4ccd635a68
author | Peter Meerwald-Stadler <pmeerw@pmeerw.net> |
---|---|
date | Sat, 28 Jan 2023 23:57:51 +0100 |
parents | bd669312f068 |
children |
rev | line source |
---|---|
0 | 1 #include "wm.h" |
2 #include "pgm.h" | |
3 | |
4 char *progname; | |
5 | |
6 void usage(void) { | |
3 | 7 fprintf(stderr, "usage: %s [-C] [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); |
0 | 8 fprintf(stderr, "\t-C\t\tprint PSNR value only\n"); |
9 fprintf(stderr, "\t-h\t\tprint usage\n"); | |
10 fprintf(stderr, "\t-i file\t\toriginal image file\n"); | |
11 fprintf(stderr, "\t-m n\t\tmultiplication factor (default auto)\n"); | |
12 fprintf(stderr, "\t-o file\t\toutput file for difference image\n"); | |
13 fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); | |
14 fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); | |
15 exit(0); | |
16 } | |
17 | |
18 int main(int argc, char *argv[]) { | |
19 | |
20 FILE *in = stdin; | |
21 FILE *out = stdout; | |
22 FILE *orig = NULL; | |
23 | |
24 gray **input_image; | |
25 gray **orig_image; | |
26 | |
27 char output_name[MAXPATHLEN] = "(stdout)"; | |
28 char input_name[MAXPATHLEN] = "(stdin)"; | |
29 char orig_name[MAXPATHLEN]; | |
30 | |
31 int in_cols, in_rows, in_format; | |
32 gray in_maxval; | |
33 int orig_cols, orig_rows, orig_format; | |
34 gray orig_maxval; | |
20
bd669312f068
suppress warnings, fix link errors
Peter Meerwald-Stadler <pmeerw@pmeerw.net>
parents:
8
diff
changeset
|
35 int cols, rows; |
0 | 36 gray maxval; |
37 int col, row; | |
38 | |
39 int c; | |
40 | |
41 int m = 0; | |
42 int min, max; | |
43 | |
44 int print_psnr = 0; | |
45 int print_psnr_only = 0; | |
46 int print_psnr_value_only = 0; | |
47 double error = 0.0; | |
48 | |
49 progname = argv[0]; | |
50 | |
51 pgm_init(&argc, argv); wm_init(); | |
52 | |
3 | 53 while ((c = getopt(argc, argv, "h?i:m:o:pPC")) != EOF) { |
0 | 54 switch (c) { |
55 case 'h': | |
56 case '?': | |
57 usage(); | |
58 break; | |
59 case 'i': | |
60 if ((orig = fopen(optarg, "rb")) == NULL) { | |
61 fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); | |
62 exit(1); | |
63 } | |
64 strcpy(orig_name, optarg); | |
65 break; | |
66 case 'm': | |
67 m = atoi(optarg); | |
68 if (m <= 0) { | |
69 fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); | |
70 exit(1); | |
71 } | |
72 break; | |
73 case 'o': | |
74 if ((out = fopen(optarg, "wb")) == NULL) { | |
75 fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); | |
76 exit(1); | |
77 } | |
78 strcpy(output_name, optarg); | |
79 break; | |
80 case 'p': | |
81 print_psnr = 1; | |
82 break; | |
83 case 'P': | |
84 print_psnr_only = 1; | |
85 break; | |
86 case 'C': | |
87 print_psnr_value_only = 1; | |
88 print_psnr_only = 1; | |
89 break; | |
90 } | |
91 } | |
92 | |
93 argc -= optind; | |
94 argv += optind; | |
95 | |
96 if (argc > 1) { | |
97 usage(); | |
98 exit(1); | |
99 } | |
100 | |
8 | 101 if (argc == 1 && *argv[0] != '-') { |
0 | 102 if ((in = fopen(argv[0], "rb")) == NULL) { |
103 fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); | |
104 exit(1); | |
105 } | |
106 else | |
107 strcpy(input_name, argv[0]); | |
8 | 108 } |
109 | |
0 | 110 if (!orig) { |
111 fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); | |
112 exit(1); | |
113 } | |
114 | |
115 pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); | |
116 | |
3 | 117 pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); |
0 | 118 |
3 | 119 if (in_cols != orig_cols || in_rows != orig_rows) { |
120 fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); | |
121 exit(1); | |
0 | 122 } |
123 | |
124 cols = in_cols; | |
125 rows = in_rows; | |
126 maxval = in_maxval; | |
127 | |
128 input_image = pgm_allocarray(cols, rows); | |
129 orig_image = pgm_allocarray(cols, rows); | |
130 | |
131 for (row = 0; row < rows; row++) { | |
132 pgm_readpgmrow(in, input_image[row], cols, in_maxval, in_format); | |
3 | 133 pgm_readpgmrow(orig, orig_image[row], cols, orig_maxval, orig_format); |
0 | 134 } |
135 | |
136 fclose(in); | |
3 | 137 fclose(orig); |
0 | 138 |
3 | 139 min = max = abs(input_image[0][0] - orig_image[0][0]); |
0 | 140 |
141 for (row = 0; row < rows; row++) { | |
142 gray *pi = input_image[row]; | |
143 gray *po = orig_image[row]; | |
144 | |
145 for (col = 0; col < cols; col++) { | |
146 int diff = abs(*pi - *po); | |
147 error += sqr(diff); | |
148 if (diff < min) min = diff; | |
149 if (diff > max) max = diff; | |
150 | |
3 | 151 pi++; |
152 po++; | |
0 | 153 } |
154 } | |
155 | |
156 for (row = 0; row < rows; row++) { | |
157 gray *pi = input_image[row]; | |
158 gray *po = orig_image[row]; | |
159 | |
160 for (col = 0; col < cols; col++) { | |
161 int diff = abs(*pi - *po); | |
3 | 162 if (m > 0) |
163 *pi = PIXELRANGE(diff * m); | |
164 else | |
165 *pi = PIXELRANGE((double) (diff - min) / (double) (max - min) * maxval); | |
0 | 166 |
167 pi++; | |
168 po++; | |
169 } | |
170 } | |
171 | |
172 if (!print_psnr_only) { | |
173 pgm_writepgminit(out, cols, rows, maxval, 0); | |
174 for (row = 0; row < rows; row++) | |
175 pgm_writepgmrow(out, input_image[row], cols, maxval, 0); | |
176 | |
177 fclose(out); | |
178 } | |
179 | |
180 pgm_freearray(input_image, rows); | |
181 pgm_freearray(orig_image, rows); | |
182 | |
183 if (print_psnr || print_psnr_only) { | |
3 | 184 double mse = error / (double) (cols * rows); |
0 | 185 double rmse = sqrt(mse); |
3 | 186 double psnr = 20.0 * log(255.0 / rmse) / log(10.0); |
0 | 187 FILE *print = print_psnr_only ? out : stderr; |
188 if (!print_psnr_value_only) { | |
189 if (mse > 0.0) | |
190 fprintf(print, "PSNR: %lf dB\n", psnr); | |
191 else | |
192 fprintf(print, "PSNR: inf\n"); | |
193 fprintf(print, "RMSE: %lf\n", rmse); | |
194 fprintf(print, "MSE: %lf\n", mse); | |
195 fprintf(print, "dmin, dmax: %d, %d\n", min, max); | |
196 } | |
197 else | |
198 fprintf(print, "%lf\n", mse > 0.0 ? psnr : 100.0); | |
199 } | |
200 | |
201 exit(0); | |
202 } |