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

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

Issue 1546003002: libwebp: update to 0.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase around clang-cl fix Created 4 years, 12 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
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 // Macroblock analysis 10 // Macroblock analysis
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 #define ALPHA_SCALE (2 * MAX_ALPHA) // scaling factor for alpha. 104 #define ALPHA_SCALE (2 * MAX_ALPHA) // scaling factor for alpha.
105 #define DEFAULT_ALPHA (-1) 105 #define DEFAULT_ALPHA (-1)
106 #define IS_BETTER_ALPHA(alpha, best_alpha) ((alpha) > (best_alpha)) 106 #define IS_BETTER_ALPHA(alpha, best_alpha) ((alpha) > (best_alpha))
107 107
108 static int FinalAlphaValue(int alpha) { 108 static int FinalAlphaValue(int alpha) {
109 alpha = MAX_ALPHA - alpha; 109 alpha = MAX_ALPHA - alpha;
110 return clip(alpha, 0, MAX_ALPHA); 110 return clip(alpha, 0, MAX_ALPHA);
111 } 111 }
112 112
113 static int GetAlpha(const VP8Histogram* const histo) { 113 static int GetAlpha(const VP8Histogram* const histo) {
114 int max_value = 0, last_non_zero = 1;
115 int k;
116 int alpha;
117 for (k = 0; k <= MAX_COEFF_THRESH; ++k) {
118 const int value = histo->distribution[k];
119 if (value > 0) {
120 if (value > max_value) max_value = value;
121 last_non_zero = k;
122 }
123 }
124 // 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer 114 // 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer
125 // values which happen to be mostly noise. This leaves the maximum precision 115 // values which happen to be mostly noise. This leaves the maximum precision
126 // for handling the useful small values which contribute most. 116 // for handling the useful small values which contribute most.
127 alpha = (max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0; 117 const int max_value = histo->max_value;
118 const int last_non_zero = histo->last_non_zero;
119 const int alpha =
120 (max_value > 1) ? ALPHA_SCALE * last_non_zero / max_value : 0;
128 return alpha; 121 return alpha;
129 } 122 }
130 123
124 static void InitHistogram(VP8Histogram* const histo) {
125 histo->max_value = 0;
126 histo->last_non_zero = 1;
127 }
128
131 static void MergeHistograms(const VP8Histogram* const in, 129 static void MergeHistograms(const VP8Histogram* const in,
132 VP8Histogram* const out) { 130 VP8Histogram* const out) {
133 int i; 131 if (in->max_value > out->max_value) {
134 for (i = 0; i <= MAX_COEFF_THRESH; ++i) { 132 out->max_value = in->max_value;
135 out->distribution[i] += in->distribution[i]; 133 }
134 if (in->last_non_zero > out->last_non_zero) {
135 out->last_non_zero = in->last_non_zero;
136 } 136 }
137 } 137 }
138 138
139 //------------------------------------------------------------------------------ 139 //------------------------------------------------------------------------------
140 // Simplified k-Means, to assign Nb segments based on alpha-histogram 140 // Simplified k-Means, to assign Nb segments based on alpha-histogram
141 141
142 static void AssignSegments(VP8Encoder* const enc, 142 static void AssignSegments(VP8Encoder* const enc,
143 const int alphas[MAX_ALPHA + 1]) { 143 const int alphas[MAX_ALPHA + 1]) {
144 // 'num_segments_' is previously validated and <= NUM_MB_SEGMENTS, but an 144 // 'num_segments_' is previously validated and <= NUM_MB_SEGMENTS, but an
145 // explicit check is needed to avoid spurious warning about 'n + 1' exceeding 145 // explicit check is needed to avoid spurious warning about 'n + 1' exceeding
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 #define MAX_UV_MODE 2 238 #define MAX_UV_MODE 2
239 239
240 static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { 240 static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) {
241 const int max_mode = MAX_INTRA16_MODE; 241 const int max_mode = MAX_INTRA16_MODE;
242 int mode; 242 int mode;
243 int best_alpha = DEFAULT_ALPHA; 243 int best_alpha = DEFAULT_ALPHA;
244 int best_mode = 0; 244 int best_mode = 0;
245 245
246 VP8MakeLuma16Preds(it); 246 VP8MakeLuma16Preds(it);
247 for (mode = 0; mode < max_mode; ++mode) { 247 for (mode = 0; mode < max_mode; ++mode) {
248 VP8Histogram histo = { { 0 } }; 248 VP8Histogram histo;
249 int alpha; 249 int alpha;
250 250
251 VP8CollectHistogram(it->yuv_in_ + Y_OFF, 251 InitHistogram(&histo);
252 VP8CollectHistogram(it->yuv_in_ + Y_OFF_ENC,
252 it->yuv_p_ + VP8I16ModeOffsets[mode], 253 it->yuv_p_ + VP8I16ModeOffsets[mode],
253 0, 16, &histo); 254 0, 16, &histo);
254 alpha = GetAlpha(&histo); 255 alpha = GetAlpha(&histo);
255 if (IS_BETTER_ALPHA(alpha, best_alpha)) { 256 if (IS_BETTER_ALPHA(alpha, best_alpha)) {
256 best_alpha = alpha; 257 best_alpha = alpha;
257 best_mode = mode; 258 best_mode = mode;
258 } 259 }
259 } 260 }
260 VP8SetIntra16Mode(it, best_mode); 261 VP8SetIntra16Mode(it, best_mode);
261 return best_alpha; 262 return best_alpha;
262 } 263 }
263 264
264 static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it, 265 static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
265 int best_alpha) { 266 int best_alpha) {
266 uint8_t modes[16]; 267 uint8_t modes[16];
267 const int max_mode = MAX_INTRA4_MODE; 268 const int max_mode = MAX_INTRA4_MODE;
268 int i4_alpha; 269 int i4_alpha;
269 VP8Histogram total_histo = { { 0 } }; 270 VP8Histogram total_histo;
270 int cur_histo = 0; 271 int cur_histo = 0;
272 InitHistogram(&total_histo);
271 273
272 VP8IteratorStartI4(it); 274 VP8IteratorStartI4(it);
273 do { 275 do {
274 int mode; 276 int mode;
275 int best_mode_alpha = DEFAULT_ALPHA; 277 int best_mode_alpha = DEFAULT_ALPHA;
276 VP8Histogram histos[2]; 278 VP8Histogram histos[2];
277 const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_]; 279 const uint8_t* const src = it->yuv_in_ + Y_OFF_ENC + VP8Scan[it->i4_];
278 280
279 VP8MakeIntra4Preds(it); 281 VP8MakeIntra4Preds(it);
280 for (mode = 0; mode < max_mode; ++mode) { 282 for (mode = 0; mode < max_mode; ++mode) {
281 int alpha; 283 int alpha;
282 284
283 memset(&histos[cur_histo], 0, sizeof(histos[cur_histo])); 285 InitHistogram(&histos[cur_histo]);
284 VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode], 286 VP8CollectHistogram(src, it->yuv_p_ + VP8I4ModeOffsets[mode],
285 0, 1, &histos[cur_histo]); 287 0, 1, &histos[cur_histo]);
286 alpha = GetAlpha(&histos[cur_histo]); 288 alpha = GetAlpha(&histos[cur_histo]);
287 if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) { 289 if (IS_BETTER_ALPHA(alpha, best_mode_alpha)) {
288 best_mode_alpha = alpha; 290 best_mode_alpha = alpha;
289 modes[it->i4_] = mode; 291 modes[it->i4_] = mode;
290 cur_histo ^= 1; // keep track of best histo so far. 292 cur_histo ^= 1; // keep track of best histo so far.
291 } 293 }
292 } 294 }
293 // accumulate best histogram 295 // accumulate best histogram
294 MergeHistograms(&histos[cur_histo ^ 1], &total_histo); 296 MergeHistograms(&histos[cur_histo ^ 1], &total_histo);
295 // Note: we reuse the original samples for predictors 297 // Note: we reuse the original samples for predictors
296 } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF)); 298 } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF_ENC));
297 299
298 i4_alpha = GetAlpha(&total_histo); 300 i4_alpha = GetAlpha(&total_histo);
299 if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) { 301 if (IS_BETTER_ALPHA(i4_alpha, best_alpha)) {
300 VP8SetIntra4Mode(it, modes); 302 VP8SetIntra4Mode(it, modes);
301 best_alpha = i4_alpha; 303 best_alpha = i4_alpha;
302 } 304 }
303 return best_alpha; 305 return best_alpha;
304 } 306 }
305 307
306 static int MBAnalyzeBestUVMode(VP8EncIterator* const it) { 308 static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
307 int best_alpha = DEFAULT_ALPHA; 309 int best_alpha = DEFAULT_ALPHA;
308 int best_mode = 0; 310 int best_mode = 0;
309 const int max_mode = MAX_UV_MODE; 311 const int max_mode = MAX_UV_MODE;
310 int mode; 312 int mode;
311 313
312 VP8MakeChroma8Preds(it); 314 VP8MakeChroma8Preds(it);
313 for (mode = 0; mode < max_mode; ++mode) { 315 for (mode = 0; mode < max_mode; ++mode) {
314 VP8Histogram histo = { { 0 } }; 316 VP8Histogram histo;
315 int alpha; 317 int alpha;
316 VP8CollectHistogram(it->yuv_in_ + U_OFF, 318 InitHistogram(&histo);
319 VP8CollectHistogram(it->yuv_in_ + U_OFF_ENC,
317 it->yuv_p_ + VP8UVModeOffsets[mode], 320 it->yuv_p_ + VP8UVModeOffsets[mode],
318 16, 16 + 4 + 4, &histo); 321 16, 16 + 4 + 4, &histo);
319 alpha = GetAlpha(&histo); 322 alpha = GetAlpha(&histo);
320 if (IS_BETTER_ALPHA(alpha, best_alpha)) { 323 if (IS_BETTER_ALPHA(alpha, best_alpha)) {
321 best_alpha = alpha; 324 best_alpha = alpha;
322 best_mode = mode; 325 best_mode = mode;
323 } 326 }
324 } 327 }
325 VP8SetIntraUVMode(it, best_mode); 328 VP8SetIntraUVMode(it, best_mode);
326 return best_alpha; 329 return best_alpha;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 int alphas[MAX_ALPHA + 1]; 398 int alphas[MAX_ALPHA + 1];
396 int alpha, uv_alpha; 399 int alpha, uv_alpha;
397 VP8EncIterator it; 400 VP8EncIterator it;
398 int delta_progress; 401 int delta_progress;
399 } SegmentJob; 402 } SegmentJob;
400 403
401 // main work call 404 // main work call
402 static int DoSegmentsJob(SegmentJob* const job, VP8EncIterator* const it) { 405 static int DoSegmentsJob(SegmentJob* const job, VP8EncIterator* const it) {
403 int ok = 1; 406 int ok = 1;
404 if (!VP8IteratorIsDone(it)) { 407 if (!VP8IteratorIsDone(it)) {
405 uint8_t tmp[32 + ALIGN_CST]; 408 uint8_t tmp[32 + WEBP_ALIGN_CST];
406 uint8_t* const scratch = (uint8_t*)DO_ALIGN(tmp); 409 uint8_t* const scratch = (uint8_t*)WEBP_ALIGN(tmp);
407 do { 410 do {
408 // Let's pretend we have perfect lossless reconstruction. 411 // Let's pretend we have perfect lossless reconstruction.
409 VP8IteratorImport(it, scratch); 412 VP8IteratorImport(it, scratch);
410 MBAnalyze(it, job->alphas, &job->alpha, &job->uv_alpha); 413 MBAnalyze(it, job->alphas, &job->alpha, &job->uv_alpha);
411 ok = VP8IteratorProgress(it, job->delta_progress); 414 ok = VP8IteratorProgress(it, job->delta_progress);
412 } while (ok && VP8IteratorNext(it)); 415 } while (ok && VP8IteratorNext(it));
413 } 416 }
414 return ok; 417 return ok;
415 } 418 }
416 419
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 enc->alpha_ = main_job.alpha / total_mb; 492 enc->alpha_ = main_job.alpha / total_mb;
490 enc->uv_alpha_ = main_job.uv_alpha / total_mb; 493 enc->uv_alpha_ = main_job.uv_alpha / total_mb;
491 AssignSegments(enc, main_job.alphas); 494 AssignSegments(enc, main_job.alphas);
492 } 495 }
493 } else { // Use only one default segment. 496 } else { // Use only one default segment.
494 ResetAllMBInfo(enc); 497 ResetAllMBInfo(enc);
495 } 498 }
496 return ok; 499 return ok;
497 } 500 }
498 501
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698