1 // Copyright 2016 Google Inc. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
9 //
10 // VP8EstimateQuality(): rough encoding quality estimate
11 //
12 // Author: Skal (pascal.massimino@gmail.com)
13
14 #include "extras/extras.h"
15 #include "webp/decode.h"
16
17 #include <math.h>
18
19 //------------------------------------------------------------------------------
20
21 #define INVALID_BIT_POS (1ull << 63)
22
23 // In most cases, we don't need to use a full arithmetic decoder, since
24 // all the header's bits are written using a uniform probability of 128.
25 // We can just parse the header as if it was bits (works in 99.999% cases).
GetBit(const uint8_t * const data,size_t nb,uint64_t max_size,uint64_t * const bit_pos)26 static WEBP_INLINE uint32_t GetBit(const uint8_t* const data, size_t nb,
27 uint64_t max_size, uint64_t* const bit_pos) {
28 uint32_t val = 0;
29 if (*bit_pos + nb <= 8 * max_size) {
30 while (nb-- > 0) {
31 const uint64_t p = (*bit_pos)++;
32 const int bit = !!(data[p >> 3] & (128 >> ((p & 7))));
33 val = (val << 1) | bit;
34 }
35 } else {
36 *bit_pos = INVALID_BIT_POS;
37 }
38 return val;
39 }
40
41 #define GET_BIT(n) GetBit(data, (n), size, &bit_pos)
42 #define CONDITIONAL_SKIP(n) (GET_BIT(1) ? GET_BIT((n)) : 0)
43
VP8EstimateQuality(const uint8_t * const data,size_t size)44 int VP8EstimateQuality(const uint8_t* const data, size_t size) {
45 size_t pos = 0;
46 uint64_t bit_pos;
47 uint64_t sig = 0x00;
48 int ok = 0;
49 int Q = -1;
50 WebPBitstreamFeatures features;
51
52 if (data == NULL) return -1;
53
54 if (WebPGetFeatures(data, size, &features) != VP8_STATUS_OK) {
55 return -1; // invalid file
56 }
57 if (features.format == 2) return 101; // lossless
58 if (features.format == 0 || features.has_animation) return -1; // mixed
59
60 while (pos < size) {
61 sig = (sig >> 8) | ((uint64_t)data[pos++] << 40);
62 if ((sig >> 24) == 0x2a019dull) {
63 ok = 1;
64 break;
65 }
66 }
67 if (!ok) return -1;
68 if (pos + 4 > size) return -1;
69
70 // Skip main Header
71 // width = (data[pos + 0] | (data[pos + 1] << 8)) & 0x3fff;
72 // height = (data[pos + 2] | (data[pos + 3] << 8)) & 0x3fff;
73 pos += 4;
74 bit_pos = pos * 8;
75
76 GET_BIT(2); // colorspace + clamp type
77
78 // Segment header
79 if (GET_BIT(1)) { // use_segment_
80 int s;
81 const int update_map = GET_BIT(1);
82 if (GET_BIT(1)) { // update data
83 const int absolute_delta = GET_BIT(1);
84 int q[4] = { 0, 0, 0, 0 };
85 for (s = 0; s < 4; ++s) {
86 if (GET_BIT(1)) {
87 q[s] = GET_BIT(7);
88 if (GET_BIT(1)) q[s] = -q[s]; // sign
89 }
90 }
91 if (absolute_delta) Q = q[0]; // just use the first segment's quantizer
92 for (s = 0; s < 4; ++s) CONDITIONAL_SKIP(7); // filter strength
93 }
94 if (update_map) {
95 for (s = 0; s < 3; ++s) CONDITIONAL_SKIP(8);
96 }
97 }
98 // Filter header
99 GET_BIT(1 + 6 + 3); // simple + level + sharpness
100 if (GET_BIT(1)) { // use_lf_delta
101 if (GET_BIT(1)) { // update lf_delta?
102 int n;
103 for (n = 0; n < 4 + 4; ++n) CONDITIONAL_SKIP(6);
104 }
105 }
106 // num partitions
107 GET_BIT(2);
108
109 // ParseQuant
110 {
111 const int base_q = GET_BIT(7);
112 /* dqy1_dc = */ CONDITIONAL_SKIP(5);
113 /* dqy2_dc = */ CONDITIONAL_SKIP(5);
114 /* dqy2_ac = */ CONDITIONAL_SKIP(5);
115 /* dquv_dc = */ CONDITIONAL_SKIP(5);
116 /* dquv_ac = */ CONDITIONAL_SKIP(5);
117
118 if (Q < 0) Q = base_q;
119 }
120 if (bit_pos == INVALID_BIT_POS) return -1;
121
122 // base mapping
123 Q = (127 - Q) * 100 / 127;
124 // correction for power-law behavior in low range
125 if (Q < 80) {
126 Q = (int)(pow(Q / 80., 1. / 0.38) * 80);
127 }
128 return Q;
129 }
130