libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

ssimulacra2_main.cc (3452B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include <stdio.h>
      7 
      8 #include <utility>
      9 
     10 #include "lib/extras/codec.h"
     11 // TODO(eustas): we should, but we can't?
     12 // #include "lib/jxl/base/span.h"
     13 #include "tools/file_io.h"
     14 #include "tools/ssimulacra2.h"
     15 
     16 int PrintUsage(char** argv) {
     17   fprintf(stderr, "Usage: %s orig.png distorted.png\n", argv[0]);
     18   fprintf(stderr,
     19           "Returns a score in range -inf..100, which correlates to subjective "
     20           "visual quality:\n");
     21   fprintf(stderr,
     22           "     30 = low quality (p10 worst output of mozjpeg -quality 30)\n");
     23   fprintf(stderr,
     24           "     50 = medium quality (average output of cjxl -q 40 or mozjpeg "
     25           "-quality 40,\n");
     26   fprintf(stderr,
     27           "                          p10 output of cjxl -q 50 or mozjpeg "
     28           "-quality 60)\n");
     29   fprintf(stderr,
     30           "     70 = high quality (average output of cjxl -q 70 or mozjpeg "
     31           "-quality 70,\n");
     32   fprintf(stderr,
     33           "                        p10 output of cjxl -q 75 or mozjpeg "
     34           "-quality 80)\n");
     35   fprintf(stderr,
     36           "     90 = very high quality (impossible to distinguish from "
     37           "original at 1:1,\n");
     38   fprintf(stderr,
     39           "                             average output of cjxl -q 90 or "
     40           "mozjpeg -quality 90)\n");
     41   return 1;
     42 }
     43 
     44 int main(int argc, char** argv) {
     45   if (argc != 3) return PrintUsage(argv);
     46 
     47   jxl::CodecInOut io[2];
     48   const char* purpose[] = {"original", "distorted"};
     49   for (size_t i = 0; i < 2; ++i) {
     50     std::vector<uint8_t> encoded;
     51     if (!jpegxl::tools::ReadFile(argv[1 + i], &encoded)) {
     52       fprintf(stderr, "Could not load %s image: %s\n", purpose[i], argv[1 + i]);
     53       return 1;
     54     }
     55     if (!jxl::SetFromBytes(jxl::Bytes(encoded), jxl::extras::ColorHints(),
     56                            &io[i])) {
     57       fprintf(stderr, "Could not decode %s image: %s\n", purpose[i],
     58               argv[1 + i]);
     59       return 1;
     60     }
     61     if (io[i].xsize() < 8 || io[i].ysize() < 8) {
     62       fprintf(stderr, "Minimum image size is 8x8 pixels\n");
     63       return 1;
     64     }
     65   }
     66   jxl::CodecInOut& io1 = io[0];
     67   jxl::CodecInOut& io2 = io[1];
     68 
     69   if (io1.xsize() != io2.xsize() || io1.ysize() != io2.ysize()) {
     70     fprintf(stderr, "Image size mismatch\n");
     71     return 1;
     72   }
     73 
     74   if (!io1.Main().HasAlpha()) {
     75     jxl::StatusOr<Msssim> msssim_or =
     76         ComputeSSIMULACRA2(io1.Main(), io2.Main());
     77     if (!msssim_or.ok()) {
     78       fprintf(stderr, "ComputeSSIMULACRA2 failed\n");
     79       return 1;
     80     }
     81     Msssim msssim = std::move(msssim_or).value();
     82     printf("%.8f\n", msssim.Score());
     83   } else {
     84     // in case of alpha transparency: blend against dark and bright backgrounds
     85     // and return the worst of both scores
     86     jxl::StatusOr<Msssim> msssim0_or =
     87         ComputeSSIMULACRA2(io1.Main(), io2.Main(), 0.1f);
     88     if (!msssim0_or.ok()) {
     89       fprintf(stderr, "ComputeSSIMULACRA2 failed\n");
     90       return 1;
     91     }
     92     Msssim msssim0 = std::move(msssim0_or).value();
     93     jxl::StatusOr<Msssim> msssim1_or =
     94         ComputeSSIMULACRA2(io1.Main(), io2.Main(), 0.9f);
     95     if (!msssim1_or.ok()) {
     96       fprintf(stderr, "ComputeSSIMULACRA2 failed\n");
     97       return 1;
     98     }
     99     Msssim msssim1 = std::move(msssim1_or).value();
    100     printf("%.8f\n", std::min(msssim0.Score(), msssim1.Score()));
    101   }
    102   return 0;
    103 }