OpenJPH Open-source implementation of JPEG2000 Part-15

Loading...
Searching...
No Matches
mse_pae.cpp
Go to the documentation of this file.
1//***************************************************************************/
2// This software is released under the 2-Clause BSD license, included
3// below.
4//
5// Copyright (c) 2019, Aous Naman
6// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
7// Copyright (c) 2019, The University of New South Wales, Australia
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// 1. Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//
16// 2. Redistributions in binary form must reproduce the above copyright
17// notice, this list of conditions and the following disclaimer in the
18// documentation and/or other materials provided with the distribution.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//***************************************************************************/
32// This file is part of the testing routines for the OpenJPH software
33// implementation.
34// File: mse_pae.cpp
35// Author: Aous Naman
36// Date: 18 March 2021
37//***************************************************************************/
38
39#include <cstdio>
40#include <cstdlib>
41#include <stdexcept>
42#include <cctype>
43#include "ojph_img_io.h"
44#include "ojph_mem.h"
45
46 using namespace ojph;
47 using namespace std;
48
49enum : ui32 {
50 UNDEFINED = 0,
51 FORMAT444 = 1,
52 FORMAT422 = 2,
53 FORMAT420 = 3,
54 FORMAT400 = 4,
55};
56
57 struct img_info {
58 img_info() {
59 num_comps = 0;
60 width = height = 0;
61 comps[0] = comps[1] = comps[2] = 0;
62 format = UNDEFINED;
63 bit_depth = 0;
64 is_signed = false;
65 }
66 ~img_info() {
67 for (ui32 i = 0; i < num_comps; ++i)
68 {
69 if (comps[i]) delete[] comps[i];
70 comps[i] = NULL;
71 }
72 }
73
74 void init(ui32 num_comps, size_t width, size_t height, ui32 bit_depth,
75 bool is_signed, ui32 format=FORMAT444)
76 {
77 assert(num_comps <= 3 && comps[0] == NULL);
78 this->num_comps = num_comps;
79 this->width = width;
80 this->height = height;
81 this->format = format;
82 this->bit_depth = bit_depth;
83 this->is_signed = is_signed;
84 for (ui32 i = 0; i < num_comps; ++i)
85 switch (format)
86 {
87 case FORMAT444:
88 case FORMAT400:
89 downsampling[i].x = downsampling[i].y = 1;
90 break;
91 case FORMAT422:
92 downsampling[i].x = i == 0 ? 1 : 2;
93 downsampling[i].y = 1;
94 break;
95 case FORMAT420:
96 downsampling[i].x = i == 0 ? 1 : 2;
97 downsampling[i].y = i == 0 ? 1 : 2;
98 break;
99 default:
100 assert(0);
101 };
102 for (ui32 i = 0; i < num_comps; ++i)
103 {
104 size_t w = (this->width + downsampling[i].x - 1) / downsampling[i].x;
105 size_t h = (this->height + downsampling[i].x - 1) / downsampling[i].x;
106 comps[i] = new si32[w * h];
107 }
108 }
109
110 bool exist() {
111 return comps[0] != NULL;
112 }
113
114 ui32 num_comps;
115 size_t width, height;
116 point downsampling[3];
117 si32 *comps[3];
118 ui32 format;
119 ui32 bit_depth;
120 bool is_signed;
121};
122
123 bool is_pnm(const char *filename)
124{
125 size_t len = strlen(filename);
126 if (len >= 4 && filename[len - 4] == '.' &&
127 toupper(filename[len - 3]) == 'P' &&
128 (toupper(filename[len - 2])== 'P' || toupper(filename[len - 2]) == 'G') &&
129 toupper(filename[len - 1]) == 'M')
130 return true;
131 return false;
132}
133
134 void load_ppm(const char *filename, img_info& img)
135{
136 ppm_in ppm;
137 ppm.set_planar(true);
138 ppm.open(filename);
139
140 ui32 num_comps = ppm.get_num_components();
141 size_t width = ppm.get_width();
142 size_t height = ppm.get_height();
143 img.init(num_comps, width, height, ppm.get_bit_depth(0), false);
144
145 width = calc_aligned_size<si32, byte_alignment>(width);
146 si32 *buffer = new si32[width];
147 line_buf line;
148 line.wrap(buffer, width, 0);
149
150 for (ui32 c = 0; c < num_comps; ++c)
151 {
152 si32 *p = img.comps[c];
153 for (ui32 h = 0; h < height; ++h)
154 {
155 ui32 w = ppm.read(&line, c);
156 memcpy(p, line.i32, w * sizeof(si32));
157 p += w;
158 }
159 }
160
161 delete[] buffer;
162}
163
164 bool is_yuv(const char *filename)
165{
166 const char *p = strchr(filename, ':'); // p is either NULL or pointing to ':'
167 if (p != NULL && p - filename >= 4 && p[-4] == '.' &&
168 toupper(p[-3]) == 'Y' && toupper(p[-2])== 'U' && toupper(p[-1]) == 'V')
169 return true;
170 return false;
171}
172
173 void load_yuv(const char *filename, img_info& img)
174{
175 const char *p = strchr(filename, ':'); // p is either NULL or pointing to ':'
176 const char *name_end = p;
177 if (p == NULL) {
178 printf("A .yuv that does not have the expected format, which is\n");
179 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
180 printf("either 444, 422, or 420\n");
181 exit(-1);
182 }
183
184 ojph::size s;
185 s.w = (ui32)atoi(++p);
186 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
187 if (p == NULL) {
188 printf("Expecting image height.\n");
189 printf("A .yuv that does not have the expected format, which is\n");
190 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
191 printf("either 444, 422, or 420\n");
192 exit(-1);
193 }
194 s.h = (ui32)atoi(++p);
195 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
196 if (p == NULL) {
197 printf("Expecting image bitdepth.\n");
198 printf("A .yuv that does not have the expected format, which is\n");
199 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
200 printf("either 444, 422, or 420\n");
201 exit(-1);
202 }
203 ui32 bit_depth = (ui32)atoi(++p);
204 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
205 if (p == NULL) {
206 printf("Expecting color subsampling format.\n");
207 printf("A .yuv that does not have the expected format, which is\n");
208 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
209 printf("either 444, 422, or 420\n");
210 exit(-1);
211 }
212 // p must be pointing to color subsampling format
213 ++p;
214 size_t len = strlen(p);
215 if (len != 3)
216 {
217 printf("Image color format must have 3 characters, %s was supplied.\n", p);
218 printf("A .yuv that does not have the expected format, which is\n");
219 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
220 printf("either 444, 422, or 420\n");
221 exit(-1);
222 }
223 ui32 num_comps;
224 point downsampling[3] = { point(1,1), point(1,1), point(1,1)};
225 ui32 format;
226 if (strcmp(p, "444") == 0)
227 {
228 num_comps = 3;
229 format = FORMAT444;
230 }
231 else if (strcmp(p, "422") == 0)
232 {
233 num_comps = 3;
234 format = FORMAT422;
235 downsampling[1].x = downsampling[2].x = 2;
236 }
237 else if (strcmp(p, "420") == 0)
238 {
239 num_comps = 3;
240 format = FORMAT420;
241 downsampling[1].x = downsampling[2].x = 2;
242 downsampling[1].y = downsampling[2].y = 2;
243 }
244 else if (strcmp(p, "400") == 0)
245 {
246 num_comps = 1;
247 format = FORMAT400;
248 }
249 else {
250 printf("Unknown image color format, %s.\n", p);
251 exit(-1);
252 }
253
254 char name_buf[2048];
255 ptrdiff_t cpy_len = name_end - filename > 2047 ? 2047 : name_end - filename;
256 strncpy(name_buf, filename, (size_t)cpy_len);
257 name_buf[cpy_len] = 0;
258
259 yuv_in yuv;
260 ui32 depths[3] = {bit_depth, bit_depth, bit_depth};
261 yuv.set_bit_depth(num_comps, depths);
262 yuv.set_img_props(s, num_comps, num_comps, downsampling);
263 yuv.open(name_buf);
264
265 img.init(num_comps, s.w, s.h, bit_depth, false, format);
266
267 size_t w = calc_aligned_size<si32, byte_alignment>(s.w);
268 si32 *buffer = new si32[w];
269 line_buf line;
270 line.wrap(buffer, w, 0);
271
272 for (ui32 c = 0; c < num_comps; ++c)
273 {
274 si32 *p = img.comps[c];
275 ui32 height = (s.h + img.downsampling[c].y - 1) / img.downsampling[c].y;
276 for (ui32 h = 0; h < height; ++h)
277 {
278 ui32 w = yuv.read(&line, c);
279 memcpy(p, line.i32, w * sizeof(si32));
280 p += w;
281 }
282 }
283
284 delete[] buffer;
285}
286
287 bool is_rawl(const char *filename)
288{
289 const char *p = strchr(filename, ':'); // p is either NULL or pointing to ':'
290 if (p != NULL && p - filename >= 5 && p[-5] == '.' &&
291 toupper(p[-4]) == 'R' && toupper(p[-3])== 'A' &&
292 toupper(p[-2]) == 'W' && toupper(p[-1]) == 'L')
293 return true;
294 return false;
295}
296
297 void load_rawl(const char *filename, img_info& img)
298{
299 const char *p = strchr(filename, ':'); // p is either NULL or pointing to ':'
300 const char *name_end = p;
301 if (p == NULL) {
302 printf("A .rawl that does not have the expected format, which is\n");
303 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp\n");
304 exit(-1);
305 }
306 ojph::size s;
307 ++p;
308 s.w = (ui32)atoi(p);
309 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
310 if (p == NULL) {
311 printf("Expecting image height.\n");
312 printf("A .rawl that does not have the expected format, which is\n");
313 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp\n");
314 exit(-1);
315 }
316 ++p;
317 s.h = (ui32)atoi(p);
318 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
319 if (p == NULL) {
320 printf("Expecting image bitdepth.\n");
321 printf("A .rawl that does not have the expected format, which is\n");
322 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp\n");
323 exit(-1);
324 }
325 ++p;
326 ui32 bit_depth = (ui32)atoi(p);
327 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
328 if (p == NULL) {
329 printf("Expecting signedness information (either 0 or 1).\n");
330 printf("A .rawl that does not have the expected format, which is\n");
331 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp, where num_comp is\n");
332 printf("either 1 or 3\n");
333 exit(-1);
334 }
335 ++p;
336 bool is_signed = *p != '0';
337 p = strchr(p, 'x'); // p is either NULL or pointing to ':'
338 if (p == NULL) {
339 printf("Expecting number of components.\n");
340 printf("A .rawl that does not have the expected format, which is\n");
341 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp, where num_comp is\n");
342 printf("either 1 or 3\n");
343 exit(-1);
344 }
345 ++p;
346 ui32 num_comps = (ui32)atoi(p);
347 if (num_comps != 1 && num_comps != 3)
348 {
349 printf("num_comp must be either 1 or 3, %s was supplied.\n", p);
350 printf("A .rawl that does not have the expected format, which is\n");
351 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp, where format is\n");
352 printf("either 1 or 3\n");
353 exit(-1);
354 }
355
356 char name_buf[2048];
357 ptrdiff_t cpy_len = name_end - filename > 2047 ? 2047 : name_end - filename;
358 strncpy(name_buf, filename, (size_t)cpy_len);
359 name_buf[cpy_len] = 0;
360
361 if (num_comps == 3)
362 img.init(num_comps, s.w, s.h, bit_depth, is_signed, FORMAT444);
363 else
364 img.init(num_comps, s.w, s.h, bit_depth, is_signed, FORMAT400);
365
366 if (is_signed)
367 {
368 if (bit_depth <= 8)
369 {
370 si8 *buffer = new si8[s.w * s.h];
371 FILE *f = fopen(name_buf, "rb");
372 if (f == NULL) {
373 printf("Error opening file %s\n", name_buf);
374 exit(-1);
375 }
376
377 for (ui32 i = 0; i < num_comps; ++i)
378 {
379 si8 *sp = buffer;
380 si32 *dp = img.comps[i];
381 if (fread(buffer, 1, s.w * s.h, f) != s.w * s.h) {
382 printf("Error reading from file %s\n", name_buf);
383 exit(-1);
384 }
385 for (ui32 j = s.w * s.h; j > 0; --j)
386 *dp++ = *sp++;
387 }
388 fclose(f);
389 delete[] buffer;
390 }
391 else if (bit_depth <= 16)
392 {
393 si16 *buffer = new si16[s.w * s.h];
394 FILE *f = fopen(name_buf, "rb");
395 if (f == NULL) {
396 printf("Error opening file %s\n", name_buf);
397 exit(-1);
398 }
399
400 for (ui32 i = 0; i < num_comps; ++i)
401 {
402 si16 *sp = buffer;
403 si32 *dp = img.comps[i];
404 if (fread(buffer, 2, s.w * s.h, f) != s.w * s.h) {
405 printf("Error reading from file %s\n", name_buf);
406 exit(-1);
407 }
408 for (ui32 j = s.w * s.h; j > 0; --j)
409 *dp++ = *sp++;
410 }
411 fclose(f);
412 delete[] buffer;
413 }
414 else
415 {
416 si32 *buffer = new si32[s.w * s.h];
417 FILE *f = fopen(name_buf, "rb");
418 if (f == NULL) {
419 printf("Error opening file %s\n", name_buf);
420 exit(-1);
421 }
422
423 for (ui32 i = 0; i < num_comps; ++i)
424 {
425 si32 *sp = buffer;
426 si32 *dp = img.comps[i];
427 if (fread(buffer, 4, s.w * s.h, f) != s.w * s.h) {
428 printf("Error reading from file %s\n", name_buf);
429 exit(-1);
430 }
431 for (ui32 j = s.w * s.h; j > 0; --j)
432 *dp++ = *sp++;
433 }
434 fclose(f);
435 delete[] buffer;
436 }
437 }
438 else
439 {
440 if (bit_depth <= 8)
441 {
442 ui8 *buffer = new ui8[s.w * s.h];
443 FILE *f = fopen(name_buf, "rb");
444 if (f == NULL) {
445 printf("Error opening file %s\n", name_buf);
446 exit(-1);
447 }
448
449 for (ui32 i = 0; i < num_comps; ++i)
450 {
451 ui8 *sp = buffer;
452 si32 *dp = img.comps[i];
453 if (fread(buffer, 1, s.w * s.h, f) != s.w * s.h) {
454 printf("Error reading from file %s\n", name_buf);
455 exit(-1);
456 }
457 for (ui32 j = s.w * s.h; j > 0; --j)
458 *dp++ = *sp++;
459 }
460 fclose(f);
461 delete[] buffer;
462 }
463 else if (bit_depth <= 16)
464 {
465 ui16 *buffer = new ui16[s.w * s.h];
466 FILE *f = fopen(name_buf, "rb");
467 if (f == NULL) {
468 printf("Error opening file %s\n", name_buf);
469 exit(-1);
470 }
471
472 for (ui32 i = 0; i < num_comps; ++i)
473 {
474 ui16 *sp = buffer;
475 si32 *dp = img.comps[i];
476 if (fread(buffer, 2, s.w * s.h, f) != s.w * s.h) {
477 printf("Error reading from file %s\n", name_buf);
478 exit(-1);
479 }
480 for (ui32 j = s.w * s.h; j > 0; --j)
481 *dp++ = *sp++;
482 }
483 fclose(f);
484 delete[] buffer;
485 }
486 else
487 {
488 ui32 *buffer = new ui32[s.w * s.h];
489 FILE *f = fopen(name_buf, "rb");
490 if (f == NULL) {
491 printf("Error opening file %s\n", name_buf);
492 exit(-1);
493 }
494
495 for (ui32 i = 0; i < num_comps; ++i)
496 {
497 ui32 *sp = buffer;
498 si32 *dp = img.comps[i];
499 if (fread(buffer, 4, s.w * s.h, f) != s.w * s.h) {
500 printf("Error reading from file %s\n", name_buf);
501 exit(-1);
502 }
503 for (ui32 j = s.w * s.h; j > 0; --j)
504 *dp++ = (si32)*sp++;
505 }
506 fclose(f);
507 delete[] buffer;
508 }
509 }
510}
511
512 void find_mse_pae(const img_info& img1, const img_info& img2,
513 float mse[3], ui32 pae[3])
514{
515 if (img1.num_comps != img2.num_comps || img1.format != img2.format ||
516 img1.width != img2.width || img1.height != img2.height ||
517 img1.bit_depth != img2.bit_depth || img1.is_signed != img2.is_signed)
518 {
519 printf("Error: mismatching images\n");
520 exit(-1);
521 }
522 for (ui32 c = 0; c < img1.num_comps; ++c)
523 {
524 size_t w, h;
525 w = (img1.width + img1.downsampling[c].x - 1) / img1.downsampling[c].x;
526 h = (img1.height + img1.downsampling[c].x - 1) / img1.downsampling[c].x;
527 double se = 0;
528 ui32 lpae = 0;
529 if (img1.is_signed)
530 for (ui32 v = 0; v < h; ++v)
531 {
532 si32 *p0 = img1.comps[c] + w * v;
533 si32 *p1 = img2.comps[c] + w * v;
534 for (ui32 s = 0; s < w; ++s)
535 {
536 si32 err = *p0++ - *p1++;
537 ui32 ae = (ui32)(err > 0 ? err : -err);
538 lpae = ae > lpae ? ae : lpae;
539 se += (double)err * (double)err;
540 }
541 }
542 else
543 for (ui32 v = 0; v < h; ++v)
544 {
545 ui32 *p0 = (ui32*)img1.comps[c] + w * v;
546 ui32 *p1 = (ui32*)img2.comps[c] + w * v;
547 for (ui32 s = 0; s < w; ++s)
548 {
549 ui32 a = *p0++;
550 ui32 b = *p1++;
551 ui32 err = a > b ? a - b : b - a;
552 lpae = err > lpae ? err : lpae;
553 se += (double)err * (double)err;
554 }
555 }
556 mse[c] = (float)se / (float)(w * h);
557 pae[c] = lpae;
558 }
559}
560
561 void find_nlt_mse_pae(const img_info& img1, const img_info& img2,
562 float mse[3], ui32 pae[3])
563{
564 if (img1.num_comps != img2.num_comps || img1.format != img2.format ||
565 img1.width != img2.width || img1.height != img2.height ||
566 img1.bit_depth != img2.bit_depth || img1.is_signed != img2.is_signed)
567 {
568 printf("Error: mismatching images\n");
569 exit(-1);
570 }
571 if (img1.is_signed)
572 for (ui32 c = 0; c < img1.num_comps; ++c)
573 {
574 size_t w, h;
575 w = (img1.width + img1.downsampling[c].x - 1) / img1.downsampling[c].x;
576 h = (img1.height + img1.downsampling[c].x - 1) / img1.downsampling[c].x;
577 double se = 0;
578 ui32 lpae = 0;
579 si32 bias = (si32)((1ULL << (img1.bit_depth - 1)) + 1);
580 for (ui32 v = 0; v < h; ++v)
581 {
582 si32 *p0 = img1.comps[c] + w * v;
583 si32 *p1 = img2.comps[c] + w * v;
584 for (ui32 s = 0; s < w; ++s)
585 {
586 si32 a = *p0++;
587 si32 b = *p1++;
588 a = (a >= 0) ? a : (- a - bias);
589 b = (b >= 0) ? b : (- b - bias);
590 ui32 err = (ui32)(a > b ? a - b : b - a);
591 lpae = err > lpae ? err : lpae;
592 se += (double)err * (double)err;
593 }
594 }
595 mse[c] = (float)se / (float)(w * h);
596 pae[c] = lpae;
597 }
598 else
599 for (ui32 c = 0; c < img1.num_comps; ++c)
600 {
601 size_t w, h;
602 w = (img1.width + img1.downsampling[c].x - 1) / img1.downsampling[c].x;
603 h = (img1.height + img1.downsampling[c].x - 1) / img1.downsampling[c].x;
604 double se = 0;
605 ui32 lpae = 0;
606 for (ui32 v = 0; v < h; ++v)
607 {
608 ui32 *p0 = (ui32*)img1.comps[c] + w * v;
609 ui32 *p1 = (ui32*)img2.comps[c] + w * v;
610 for (ui32 s = 0; s < w; ++s)
611 {
612 ui32 a = *p0++;
613 ui32 b = *p1++;
614 ui32 err = a > b ? a - b : b - a;
615 lpae = err > lpae ? err : lpae;
616 se += (double)err * (double)err;
617 }
618 }
619 mse[c] = (float)se / (float)(w * h);
620 pae[c] = lpae;
621 }
622}
623
624 int main(int argc, char *argv[])
625{
626 if (argc < 3)
627 {
628 printf("mse_pae expects two arguments <filename1, filename2>\n");
629 printf("A third optional argment is \"-nlt\".\n");
630 exit(-1);
631 }
632
633 bool nlt = false;
634 if (argc == 4)
635 {
636 if (strcmp("-nlt", argv[3]) == 0)
637 nlt = true;
638 else {
639 printf("unknown 4th parameter %s\n", argv[3]);
640 exit(-1);
641 }
642 }
643
644
645 img_info img1, img2;
646 try {
647 if (is_pnm(argv[1]))
648 load_ppm(argv[1], img1);
649 else if (is_yuv(argv[1]))
650 load_yuv(argv[1], img1);
651 else if (is_rawl(argv[1]))
652 load_rawl(argv[1], img1);
653 else {
654 printf("mse_pae does not know file format of %s\n", argv[1]);
655 printf("or a .yuv that does not have the expected format, which is\n");
656 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
657 printf("either 444, 422, or 420, or wrongly format .rawl, which has\n");
658 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp format.\n");
659 exit(-1);
660 }
661 }
662 catch (const std::exception& e)
663 {
664 const char *p = e.what();
665 if (strncmp(p, "ojph error", 10) != 0)
666 printf("%s\n", p);
667 exit(-1);
668 }
669
670 try {
671 if (is_pnm(argv[2]))
672 load_ppm(argv[2], img2);
673 else if (is_yuv(argv[2]))
674 load_yuv(argv[2], img2);
675 else if (is_rawl(argv[2]))
676 load_rawl(argv[2], img2);
677 else {
678 printf("mse_pae does not know file format of %s\n", argv[2]);
679 printf("or a .yuv that does not have the expected format, which is\n");
680 printf(".yuv:widthxheightxbitdepthxformat, where format is\n");
681 printf("either 444, 422, or 420, or wrongly format .rawl, which has\n");
682 printf(".rawl:widthxheightxbitdepthxsignedxnum_comp format.\n");
683 exit(-1);
684 }
685 }
686 catch (const std::exception& e)
687 {
688 const char *p = e.what();
689 if (strncmp(p, "ojph error", 10) != 0)
690 printf("%s\n", p);
691 exit(-1);
692 }
693
694 float mse[3]; ui32 pae[3];
695 if (!nlt)
696 find_mse_pae(img1, img2, mse, pae);
697 else
698 find_nlt_mse_pae(img1, img2, mse, pae);
699
700 for (ui32 c = 0; c < img1.num_comps; ++c)
701 printf("%f %d\n", mse[c], pae[c]);
702
703 return 0;
704}
705
706
ojph::line_buf
Definition ojph_mem.h:160
ojph::line_buf::wrap
void wrap(T *buffer, size_t num_ele, ui32 pre_size)
ojph::line_buf::i32
si32 * i32
Definition ojph_mem.h:184
ojph::ppm_in
Definition ojph_img_io.h:82
ojph::ppm_in::get_height
ui32 get_height()
Definition ojph_img_io.h:117
ojph::ppm_in::open
void open(const char *filename)
Definition ojph_img_io.cpp:245
ojph::ppm_in::get_num_components
ui32 get_num_components()
Definition ojph_img_io.h:119
ojph::ppm_in::set_planar
void set_planar(bool planar)
Definition ojph_img_io.h:113
ojph::ppm_in::get_width
ui32 get_width()
Definition ojph_img_io.h:116
ojph::ppm_in::get_bit_depth
ui32 get_bit_depth(ui32 comp_num)
Definition ojph_img_io.h:120
ojph::ppm_in::read
virtual ui32 read(const line_buf *line, ui32 comp_num)
Definition ojph_img_io.cpp:338
ojph::yuv_in
Definition ojph_img_io.h:348
ojph::yuv_in::read
virtual ui32 read(const line_buf *line, ui32 comp_num)
Definition ojph_img_io.cpp:1321
ojph::yuv_in::open
void open(const char *filename)
Definition ojph_img_io.cpp:1296
ojph::yuv_in::set_img_props
void set_img_props(const size &s, ui32 num_components, ui32 num_downsampling, const point *downsampling)
Definition ojph_img_io.cpp:1351
ojph::yuv_in::set_bit_depth
void set_bit_depth(ui32 num_bit_depths, ui32 *bit_depth)
Definition ojph_img_io.cpp:1378
find_mse_pae
void find_mse_pae(const img_info &img1, const img_info &img2, float mse[3], ui32 pae[3])
Definition mse_pae.cpp:512
main
int main(int argc, char *argv[])
Definition mse_pae.cpp:624
find_nlt_mse_pae
void find_nlt_mse_pae(const img_info &img1, const img_info &img2, float mse[3], ui32 pae[3])
Definition mse_pae.cpp:561
is_yuv
bool is_yuv(const char *filename)
Definition mse_pae.cpp:164
load_rawl
void load_rawl(const char *filename, img_info &img)
Definition mse_pae.cpp:297
FORMAT444
@ FORMAT444
Definition mse_pae.cpp:51
UNDEFINED
@ UNDEFINED
Definition mse_pae.cpp:50
FORMAT400
@ FORMAT400
Definition mse_pae.cpp:54
FORMAT420
@ FORMAT420
Definition mse_pae.cpp:53
FORMAT422
@ FORMAT422
Definition mse_pae.cpp:52
is_rawl
bool is_rawl(const char *filename)
Definition mse_pae.cpp:287
is_pnm
bool is_pnm(const char *filename)
Definition mse_pae.cpp:123
load_ppm
void load_ppm(const char *filename, img_info &img)
Definition mse_pae.cpp:134
load_yuv
void load_yuv(const char *filename, img_info &img)
Definition mse_pae.cpp:173
ojph
Definition ojph_img_io.h:52
ojph::si8
int8_t si8
Definition ojph_defs.h:51
ojph::calc_aligned_size
size_t calc_aligned_size(size_t size)
Definition ojph_arch.h:302
ojph::ui16
uint16_t ui16
Definition ojph_defs.h:52
ojph::si32
int32_t si32
Definition ojph_defs.h:55
ojph::si16
int16_t si16
Definition ojph_defs.h:53
ojph::ui32
uint32_t ui32
Definition ojph_defs.h:54
ojph::ui8
uint8_t ui8
Definition ojph_defs.h:50
ojph_img_io.h
ojph_mem.h
img_info
Definition mse_pae.cpp:57
img_info::height
size_t height
Definition mse_pae.cpp:115
img_info::img_info
img_info()
Definition mse_pae.cpp:58
img_info::init
void init(ui32 num_comps, size_t width, size_t height, ui32 bit_depth, bool is_signed, ui32 format=FORMAT444)
Definition mse_pae.cpp:74
img_info::comps
si32 * comps[3]
Definition mse_pae.cpp:117
img_info::~img_info
~img_info()
Definition mse_pae.cpp:66
img_info::downsampling
point downsampling[3]
Definition mse_pae.cpp:116
img_info::is_signed
bool is_signed
Definition mse_pae.cpp:120
img_info::num_comps
ui32 num_comps
Definition mse_pae.cpp:114
img_info::exist
bool exist()
Definition mse_pae.cpp:110
img_info::format
ui32 format
Definition mse_pae.cpp:118
img_info::bit_depth
ui32 bit_depth
Definition mse_pae.cpp:119
img_info::width
size_t width
Definition mse_pae.cpp:115
ojph::point
Definition ojph_base.h:58
ojph::point::y
ui32 y
Definition ojph_base.h:60
ojph::point::x
ui32 x
Definition ojph_base.h:60
ojph::size
Definition ojph_base.h:48
ojph::size::w
ui32 w
Definition ojph_base.h:50
ojph::size::h
ui32 h
Definition ojph_base.h:51