diff options
Diffstat (limited to 'src/3rdparty/libwebp/src/enc/analysis.c')
-rw-r--r-- | src/3rdparty/libwebp/src/enc/analysis.c | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/src/3rdparty/libwebp/src/enc/analysis.c b/src/3rdparty/libwebp/src/enc/analysis.c index 7d4cfdc..e019465 100644 --- a/src/3rdparty/libwebp/src/enc/analysis.c +++ b/src/3rdparty/libwebp/src/enc/analysis.c @@ -30,7 +30,7 @@ static void SmoothSegmentMap(VP8Encoder* const enc) { const int w = enc->mb_w_; const int h = enc->mb_h_; const int majority_cnt_3_x_3_grid = 5; - uint8_t* const tmp = (uint8_t*)WebPSafeMalloc((uint64_t)w * h, sizeof(*tmp)); + uint8_t* const tmp = (uint8_t*)WebPSafeMalloc(w * h, sizeof(*tmp)); assert((uint64_t)(w * h) == (uint64_t)w * h); // no overflow, as per spec if (tmp == NULL) return; @@ -63,7 +63,7 @@ static void SmoothSegmentMap(VP8Encoder* const enc) { mb->segment_ = tmp[x + y * w]; } } - free(tmp); + WebPSafeFree(tmp); } //------------------------------------------------------------------------------ @@ -141,7 +141,11 @@ static void MergeHistograms(const VP8Histogram* const in, static void AssignSegments(VP8Encoder* const enc, const int alphas[MAX_ALPHA + 1]) { - const int nb = enc->segment_hdr_.num_segments_; + // 'num_segments_' is previously validated and <= NUM_MB_SEGMENTS, but an + // explicit check is needed to avoid spurious warning about 'n + 1' exceeding + // array bounds of 'centers' with some compilers (noticed with gcc-4.9). + const int nb = (enc->segment_hdr_.num_segments_ < NUM_MB_SEGMENTS) ? + enc->segment_hdr_.num_segments_ : NUM_MB_SEGMENTS; int centers[NUM_MB_SEGMENTS]; int weighted_average = 0; int map[MAX_ALPHA + 1]; @@ -151,6 +155,7 @@ static void AssignSegments(VP8Encoder* const enc, int accum[NUM_MB_SEGMENTS], dist_accum[NUM_MB_SEGMENTS]; assert(nb >= 1); + assert(nb <= NUM_MB_SEGMENTS); // bracket the input for (n = 0; n <= MAX_ALPHA && alphas[n] == 0; ++n) {} @@ -225,18 +230,15 @@ static void AssignSegments(VP8Encoder* const enc, // susceptibility and set best modes for this macroblock. // Segment assignment is done later. -// Number of modes to inspect for alpha_ evaluation. For high-quality settings -// (method >= FAST_ANALYSIS_METHOD) we don't need to test all the possible modes -// during the analysis phase. -#define FAST_ANALYSIS_METHOD 4 // method above which we do partial analysis +// Number of modes to inspect for alpha_ evaluation. We don't need to test all +// the possible modes during the analysis phase: we risk falling into a local +// optimum, or be subject to boundary effect #define MAX_INTRA16_MODE 2 #define MAX_INTRA4_MODE 2 #define MAX_UV_MODE 2 static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { - const int max_mode = - (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_INTRA16_MODE - : NUM_PRED_MODES; + const int max_mode = MAX_INTRA16_MODE; int mode; int best_alpha = DEFAULT_ALPHA; int best_mode = 0; @@ -262,9 +264,7 @@ static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) { static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it, int best_alpha) { uint8_t modes[16]; - const int max_mode = - (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_INTRA4_MODE - : NUM_BMODES; + const int max_mode = MAX_INTRA4_MODE; int i4_alpha; VP8Histogram total_histo = { { 0 } }; int cur_histo = 0; @@ -306,10 +306,9 @@ static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it, static int MBAnalyzeBestUVMode(VP8EncIterator* const it) { int best_alpha = DEFAULT_ALPHA; int best_mode = 0; - const int max_mode = - (it->enc_->method_ >= FAST_ANALYSIS_METHOD) ? MAX_UV_MODE - : NUM_PRED_MODES; + const int max_mode = MAX_UV_MODE; int mode; + VP8MakeChroma8Preds(it); for (mode = 0; mode < max_mode; ++mode) { VP8Histogram histo = { { 0 } }; @@ -425,7 +424,7 @@ static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) { // initialize the job struct with some TODOs static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job, int start_row, int end_row) { - WebPWorkerInit(&job->worker); + WebPGetWorkerInterface()->Init(&job->worker); job->worker.data1 = job; job->worker.data2 = &job->it; job->worker.hook = (WebPWorkerHook)DoSegmentsJob; @@ -458,6 +457,8 @@ int VP8EncAnalyze(VP8Encoder* const enc) { #else const int do_mt = 0; #endif + const WebPWorkerInterface* const worker_interface = + WebPGetWorkerInterface(); SegmentJob main_job; if (do_mt) { SegmentJob side_job; @@ -467,23 +468,23 @@ int VP8EncAnalyze(VP8Encoder* const enc) { InitSegmentJob(enc, &side_job, split_row, last_row); // we don't need to call Reset() on main_job.worker, since we're calling // WebPWorkerExecute() on it - ok &= WebPWorkerReset(&side_job.worker); + ok &= worker_interface->Reset(&side_job.worker); // launch the two jobs in parallel if (ok) { - WebPWorkerLaunch(&side_job.worker); - WebPWorkerExecute(&main_job.worker); - ok &= WebPWorkerSync(&side_job.worker); - ok &= WebPWorkerSync(&main_job.worker); + worker_interface->Launch(&side_job.worker); + worker_interface->Execute(&main_job.worker); + ok &= worker_interface->Sync(&side_job.worker); + ok &= worker_interface->Sync(&main_job.worker); } - WebPWorkerEnd(&side_job.worker); + worker_interface->End(&side_job.worker); if (ok) MergeJobs(&side_job, &main_job); // merge results together } else { // Even for single-thread case, we use the generic Worker tools. InitSegmentJob(enc, &main_job, 0, last_row); - WebPWorkerExecute(&main_job.worker); - ok &= WebPWorkerSync(&main_job.worker); + worker_interface->Execute(&main_job.worker); + ok &= worker_interface->Sync(&main_job.worker); } - WebPWorkerEnd(&main_job.worker); + worker_interface->End(&main_job.worker); if (ok) { enc->alpha_ = main_job.alpha / total_mb; enc->uv_alpha_ = main_job.uv_alpha / total_mb; |