Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: third_party/libwebp/enc/filter.c

Issue 2149863002: libwebp: update to v0.5.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libwebp/enc/backward_references.c ('k') | third_party/libwebp/enc/histogram.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 Google Inc. All Rights Reserved. 1 // Copyright 2011 Google Inc. All Rights Reserved.
2 // 2 //
3 // Use of this source code is governed by a BSD-style license 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 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 5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may 6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree. 7 // be found in the AUTHORS file in the root of the source tree.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 // 9 //
10 // Selecting filter level 10 // Selecting filter level
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 VP8HFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); 100 VP8HFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
101 VP8HFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); 101 VP8HFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
102 VP8VFilter16i(y_dst, BPS, limit, ilevel, hev_thresh); 102 VP8VFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
103 VP8VFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh); 103 VP8VFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
104 } 104 }
105 } 105 }
106 106
107 //------------------------------------------------------------------------------ 107 //------------------------------------------------------------------------------
108 // SSIM metric 108 // SSIM metric
109 109
110 enum { KERNEL = 3 };
111 static const double kMinValue = 1.e-10; // minimal threshold 110 static const double kMinValue = 1.e-10; // minimal threshold
112 111
113 void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst) { 112 void VP8SSIMAddStats(const VP8DistoStats* const src, VP8DistoStats* const dst) {
114 dst->w += src->w; 113 dst->w += src->w;
115 dst->xm += src->xm; 114 dst->xm += src->xm;
116 dst->ym += src->ym; 115 dst->ym += src->ym;
117 dst->xxm += src->xxm; 116 dst->xxm += src->xxm;
118 dst->xym += src->xym; 117 dst->xym += src->xym;
119 dst->yym += src->yym; 118 dst->yym += src->yym;
120 } 119 }
121 120
122 static void VP8SSIMAccumulate(const uint8_t* src1, int stride1, 121 double VP8SSIMGet(const VP8DistoStats* const stats) {
123 const uint8_t* src2, int stride2,
124 int xo, int yo, int W, int H,
125 DistoStats* const stats) {
126 const int ymin = (yo - KERNEL < 0) ? 0 : yo - KERNEL;
127 const int ymax = (yo + KERNEL > H - 1) ? H - 1 : yo + KERNEL;
128 const int xmin = (xo - KERNEL < 0) ? 0 : xo - KERNEL;
129 const int xmax = (xo + KERNEL > W - 1) ? W - 1 : xo + KERNEL;
130 int x, y;
131 src1 += ymin * stride1;
132 src2 += ymin * stride2;
133 for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) {
134 for (x = xmin; x <= xmax; ++x) {
135 const int s1 = src1[x];
136 const int s2 = src2[x];
137 stats->w += 1;
138 stats->xm += s1;
139 stats->ym += s2;
140 stats->xxm += s1 * s1;
141 stats->xym += s1 * s2;
142 stats->yym += s2 * s2;
143 }
144 }
145 }
146
147 double VP8SSIMGet(const DistoStats* const stats) {
148 const double xmxm = stats->xm * stats->xm; 122 const double xmxm = stats->xm * stats->xm;
149 const double ymym = stats->ym * stats->ym; 123 const double ymym = stats->ym * stats->ym;
150 const double xmym = stats->xm * stats->ym; 124 const double xmym = stats->xm * stats->ym;
151 const double w2 = stats->w * stats->w; 125 const double w2 = stats->w * stats->w;
152 double sxx = stats->xxm * stats->w - xmxm; 126 double sxx = stats->xxm * stats->w - xmxm;
153 double syy = stats->yym * stats->w - ymym; 127 double syy = stats->yym * stats->w - ymym;
154 double sxy = stats->xym * stats->w - xmym; 128 double sxy = stats->xym * stats->w - xmym;
155 double C1, C2; 129 double C1, C2;
156 double fnum; 130 double fnum;
157 double fden; 131 double fden;
158 // small errors are possible, due to rounding. Clamp to zero. 132 // small errors are possible, due to rounding. Clamp to zero.
159 if (sxx < 0.) sxx = 0.; 133 if (sxx < 0.) sxx = 0.;
160 if (syy < 0.) syy = 0.; 134 if (syy < 0.) syy = 0.;
161 C1 = 6.5025 * w2; 135 C1 = 6.5025 * w2;
162 C2 = 58.5225 * w2; 136 C2 = 58.5225 * w2;
163 fnum = (2 * xmym + C1) * (2 * sxy + C2); 137 fnum = (2 * xmym + C1) * (2 * sxy + C2);
164 fden = (xmxm + ymym + C1) * (sxx + syy + C2); 138 fden = (xmxm + ymym + C1) * (sxx + syy + C2);
165 return (fden != 0.) ? fnum / fden : kMinValue; 139 return (fden != 0.) ? fnum / fden : kMinValue;
166 } 140 }
167 141
168 double VP8SSIMGetSquaredError(const DistoStats* const s) { 142 double VP8SSIMGetSquaredError(const VP8DistoStats* const s) {
169 if (s->w > 0.) { 143 if (s->w > 0.) {
170 const double iw2 = 1. / (s->w * s->w); 144 const double iw2 = 1. / (s->w * s->w);
171 const double sxx = s->xxm * s->w - s->xm * s->xm; 145 const double sxx = s->xxm * s->w - s->xm * s->xm;
172 const double syy = s->yym * s->w - s->ym * s->ym; 146 const double syy = s->yym * s->w - s->ym * s->ym;
173 const double sxy = s->xym * s->w - s->xm * s->ym; 147 const double sxy = s->xym * s->w - s->xm * s->ym;
174 const double SSE = iw2 * (sxx + syy - 2. * sxy); 148 const double SSE = iw2 * (sxx + syy - 2. * sxy);
175 if (SSE > kMinValue) return SSE; 149 if (SSE > kMinValue) return SSE;
176 } 150 }
177 return kMinValue; 151 return kMinValue;
178 } 152 }
179 153
154 #define LIMIT(A, M) ((A) > (M) ? (M) : (A))
155 static void VP8SSIMAccumulateRow(const uint8_t* src1, int stride1,
156 const uint8_t* src2, int stride2,
157 int y, int W, int H,
158 VP8DistoStats* const stats) {
159 int x = 0;
160 const int w0 = LIMIT(VP8_SSIM_KERNEL, W);
161 for (x = 0; x < w0; ++x) {
162 VP8SSIMAccumulateClipped(src1, stride1, src2, stride2, x, y, W, H, stats);
163 }
164 for (; x <= W - 8 + VP8_SSIM_KERNEL; ++x) {
165 VP8SSIMAccumulate(
166 src1 + (y - VP8_SSIM_KERNEL) * stride1 + (x - VP8_SSIM_KERNEL), stride1,
167 src2 + (y - VP8_SSIM_KERNEL) * stride2 + (x - VP8_SSIM_KERNEL), stride2,
168 stats);
169 }
170 for (; x < W; ++x) {
171 VP8SSIMAccumulateClipped(src1, stride1, src2, stride2, x, y, W, H, stats);
172 }
173 }
174
180 void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1, 175 void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1,
181 const uint8_t* src2, int stride2, 176 const uint8_t* src2, int stride2,
182 int W, int H, DistoStats* const stats) { 177 int W, int H, VP8DistoStats* const stats) {
183 int x, y; 178 int x, y;
184 for (y = 0; y < H; ++y) { 179 const int h0 = LIMIT(VP8_SSIM_KERNEL, H);
180 const int h1 = LIMIT(VP8_SSIM_KERNEL, H - VP8_SSIM_KERNEL);
181 for (y = 0; y < h0; ++y) {
185 for (x = 0; x < W; ++x) { 182 for (x = 0; x < W; ++x) {
186 VP8SSIMAccumulate(src1, stride1, src2, stride2, x, y, W, H, stats); 183 VP8SSIMAccumulateClipped(src1, stride1, src2, stride2, x, y, W, H, stats);
184 }
185 }
186 for (; y < h1; ++y) {
187 VP8SSIMAccumulateRow(src1, stride1, src2, stride2, y, W, H, stats);
188 }
189 for (; y < H; ++y) {
190 for (x = 0; x < W; ++x) {
191 VP8SSIMAccumulateClipped(src1, stride1, src2, stride2, x, y, W, H, stats);
187 } 192 }
188 } 193 }
189 } 194 }
195 #undef LIMIT
190 196
191 static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) { 197 static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) {
192 int x, y; 198 int x, y;
193 DistoStats s = { .0, .0, .0, .0, .0, .0 }; 199 VP8DistoStats s = { .0, .0, .0, .0, .0, .0 };
194 200
195 // compute SSIM in a 10 x 10 window 201 // compute SSIM in a 10 x 10 window
196 for (x = 3; x < 13; x++) { 202 for (y = VP8_SSIM_KERNEL; y < 16 - VP8_SSIM_KERNEL; y++) {
197 for (y = 3; y < 13; y++) { 203 for (x = VP8_SSIM_KERNEL; x < 16 - VP8_SSIM_KERNEL; x++) {
198 VP8SSIMAccumulate(yuv1 + Y_OFF_ENC, BPS, yuv2 + Y_OFF_ENC, BPS, 204 VP8SSIMAccumulateClipped(yuv1 + Y_OFF_ENC, BPS, yuv2 + Y_OFF_ENC, BPS,
199 x, y, 16, 16, &s); 205 x, y, 16, 16, &s);
200 } 206 }
201 } 207 }
202 for (x = 1; x < 7; x++) { 208 for (x = 1; x < 7; x++) {
203 for (y = 1; y < 7; y++) { 209 for (y = 1; y < 7; y++) {
204 VP8SSIMAccumulate(yuv1 + U_OFF_ENC, BPS, yuv2 + U_OFF_ENC, BPS, 210 VP8SSIMAccumulateClipped(yuv1 + U_OFF_ENC, BPS, yuv2 + U_OFF_ENC, BPS,
205 x, y, 8, 8, &s); 211 x, y, 8, 8, &s);
206 VP8SSIMAccumulate(yuv1 + V_OFF_ENC, BPS, yuv2 + V_OFF_ENC, BPS, 212 VP8SSIMAccumulateClipped(yuv1 + V_OFF_ENC, BPS, yuv2 + V_OFF_ENC, BPS,
207 x, y, 8, 8, &s); 213 x, y, 8, 8, &s);
208 } 214 }
209 } 215 }
210 return VP8SSIMGet(&s); 216 return VP8SSIMGet(&s);
211 } 217 }
212 218
213 //------------------------------------------------------------------------------ 219 //------------------------------------------------------------------------------
214 // Exposed APIs: Encoder should call the following 3 functions to adjust 220 // Exposed APIs: Encoder should call the following 3 functions to adjust
215 // loop filter strength 221 // loop filter strength
216 222
217 void VP8InitFilter(VP8EncIterator* const it) { 223 void VP8InitFilter(VP8EncIterator* const it) {
218 if (it->lf_stats_ != NULL) { 224 if (it->lf_stats_ != NULL) {
219 int s, i; 225 int s, i;
220 for (s = 0; s < NUM_MB_SEGMENTS; s++) { 226 for (s = 0; s < NUM_MB_SEGMENTS; s++) {
221 for (i = 0; i < MAX_LF_LEVELS; i++) { 227 for (i = 0; i < MAX_LF_LEVELS; i++) {
222 (*it->lf_stats_)[s][i] = 0; 228 (*it->lf_stats_)[s][i] = 0;
223 } 229 }
224 } 230 }
231 VP8SSIMDspInit();
225 } 232 }
226 } 233 }
227 234
228 void VP8StoreFilterStats(VP8EncIterator* const it) { 235 void VP8StoreFilterStats(VP8EncIterator* const it) {
229 int d; 236 int d;
230 VP8Encoder* const enc = it->enc_; 237 VP8Encoder* const enc = it->enc_;
231 const int s = it->mb_->segment_; 238 const int s = it->mb_->segment_;
232 const int level0 = enc->dqm_[s].fstrength_; 239 const int level0 = enc->dqm_[s].fstrength_;
233 240
234 // explore +/-quant range of values around level0 241 // explore +/-quant range of values around level0
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 297 }
291 if (max_level < dqm->fstrength_) { 298 if (max_level < dqm->fstrength_) {
292 max_level = dqm->fstrength_; 299 max_level = dqm->fstrength_;
293 } 300 }
294 } 301 }
295 enc->filter_hdr_.level_ = max_level; 302 enc->filter_hdr_.level_ = max_level;
296 } 303 }
297 } 304 }
298 305
299 // ----------------------------------------------------------------------------- 306 // -----------------------------------------------------------------------------
OLDNEW
« no previous file with comments | « third_party/libwebp/enc/backward_references.c ('k') | third_party/libwebp/enc/histogram.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698