int VP8EncAnalyze(VP8Encoder* const enc) { int ok = 1; const int do_segments = (enc->segment_hdr_.num_segments_ > 1) || (enc->method_ <= 2); // for methods 0,1,2, we need preds_[] to be filled. if (do_segments) { int alphas[MAX_ALPHA + 1] = { 0 }; VP8EncIterator it; VP8IteratorInit(enc, &it); enc->uv_alpha_ = 0; do { VP8IteratorImport(&it); MBAnalyze(&it, alphas, &enc->uv_alpha_); ok = VP8IteratorProgress(&it, 20); // Let's pretend we have perfect lossless reconstruction. } while (ok && VP8IteratorNext(&it, it.yuv_in_)); enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_; if (ok) AssignSegments(enc, alphas); } else { // Use only one default segment. int n; for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { DefaultMBInfo(&enc->mb_info_[n]); } // Default susceptibilities. enc->dqm_[0].alpha_ = 0; enc->dqm_[0].beta_ = 0; enc->uv_alpha_ = 0; // we can't compute this one. WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); } return ok; }
int VP8EncFinishAlpha(VP8Encoder* const enc) { if (enc->has_alpha_) { if (enc->thread_level_ > 0) { WebPWorker* const worker = &enc->alpha_worker_; if (!WebPWorkerSync(worker)) return 0; // error } } return WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); }
int VP8IteratorProgress(const VP8EncIterator* const it, int delta) { VP8Encoder* const enc = it->enc_; if (delta && enc->pic_->progress_hook != NULL) { const int done = it->count_down0_ - it->count_down_; const int percent = (it->count_down0_ <= 0) ? it->percent0_ : it->percent0_ + delta * done / it->count_down0_; return WebPReportProgress(enc->pic_, percent, &enc->percent_); } return 1; }
static void ResetAllMBInfo(VP8Encoder* const enc) { int n; for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { DefaultMBInfo(&enc->mb_info_[n]); } // Default susceptibilities. enc->dqm_[0].alpha_ = 0; enc->dqm_[0].beta_ = 0; // Note: we can't compute this alpha_ / uv_alpha_. WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); }
static void ResetAllMBInfo(VP8Encoder* const enc) { int n; for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) { DefaultMBInfo(&enc->mb_info_[n]); } enc->dqm_[0].alpha_ = 0; enc->dqm_[0].beta_ = 0; WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); }
static void StoreStats(VP8Encoder* const enc) { WebPAuxStats* const stats = enc->pic_->stats; if (stats != NULL) { int i, s; for (i = 0; i < NUM_MB_SEGMENTS; ++i) { stats->segment_level[i] = enc->dqm_[i].fstrength_; stats->segment_quant[i] = enc->dqm_[i].quant_; for (s = 0; s <= 2; ++s) { stats->residual_bytes[s][i] = enc->residual_bytes_[s][i]; } } FinalizePSNR(enc); stats->coded_size = enc->coded_size_; for (i = 0; i < 3; ++i) { stats->block_count[i] = enc->block_count_[i]; } } WebPReportProgress(enc->pic_, 100, &enc->percent_); // done! }
int VP8EncFinishAlpha(VP8Encoder* const enc) { if (enc->has_alpha_) { const WebPConfig* config = enc->config_; uint8_t* tmp_data = NULL; size_t tmp_size = 0; const int effort_level = config->method; // maps to [0..6] const WEBP_FILTER_TYPE filter = (config->alpha_filtering == 0) ? WEBP_FILTER_NONE : (config->alpha_filtering == 1) ? WEBP_FILTER_FAST : WEBP_FILTER_BEST; if (!EncodeAlpha(enc, config->alpha_quality, config->alpha_compression, filter, effort_level, &tmp_data, &tmp_size)) { return 0; } if (tmp_size != (uint32_t)tmp_size) { // Sanity check. free(tmp_data); return 0; } enc->alpha_data_size_ = (uint32_t)tmp_size; enc->alpha_data_ = tmp_data; } return WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_); }