1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "guetzli/quality.h"
18 
19 namespace guetzli {
20 
21 namespace {
22 
23 constexpr int kLowestQuality = 70;
24 constexpr int kHighestQuality = 110;
25 
26 // Butteraugli scores that correspond to JPEG quality levels, starting at
27 // kLowestQuality. They were computed by taking median BA scores of JPEGs
28 // generated using libjpeg-turbo at given quality from a set of PNGs.
29 // The scores above quality level 100 are just linearly decreased so that score
30 // for 110 is 90% of the score for 100.
31 const double kScoreForQuality[] = {
32   2.810761,  // 70
33   2.729300,
34   2.689687,
35   2.636811,
36   2.547863,
37   2.525400,
38   2.473416,
39   2.366133,
40   2.338078,
41   2.318654,
42   2.201674,  // 80
43   2.145517,
44   2.087322,
45   2.009328,
46   1.945456,
47   1.900112,
48   1.805701,
49   1.750194,
50   1.644175,
51   1.562165,
52   1.473608,  // 90
53   1.382021,
54   1.294298,
55   1.185402,
56   1.066781,
57   0.971769,  // 95
58   0.852901,
59   0.724544,
60   0.611302,
61   0.443185,
62   0.211578,  // 100
63   0.209462,
64   0.207346,
65   0.205230,
66   0.203114,
67   0.200999,  // 105
68   0.198883,
69   0.196767,
70   0.194651,
71   0.192535,
72   0.190420,  // 110
73   0.190420,
74 };
75 
76 }  // namespace
77 
ButteraugliScoreForQuality(double quality)78 double ButteraugliScoreForQuality(double quality) {
79   if (quality < kLowestQuality) quality = kLowestQuality;
80   if (quality > kHighestQuality) quality = kHighestQuality;
81   int index = static_cast<int>(quality);
82   double mix = quality - index;
83   return kScoreForQuality[index - kLowestQuality] * (1 - mix) +
84       kScoreForQuality[index - kLowestQuality + 1] * mix;
85 }
86 
87 }  // namespace guetzli
88