mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
Add progress hook granularity in lossless
A WebPPicture instance is necessary to call WebPReportProgress() which sets WebPPicture::error_code so as well use WebPEncodingSetError() to record errors too, instead of functions returning a WebPEncodingError. However there must be one WebPPicture instance per thread, with error codes merged at sync time. A mutex could simplify that but it is not the objective of this change. https://groups.google.com/a/webmproject.org/g/webp-discuss/c/yOiP8APubgc/m/vCTvxl6ODgAJ Change-Id: Ia1a8f9d1199202e1c88484ce719b0180a80447ce
This commit is contained in:
parent
26139c7398
commit
ec178f2c7f
@ -86,7 +86,7 @@ static int EncodeLossless(const uint8_t* const data, int width, int height,
|
|||||||
// a decoder bug related to alpha with color cache.
|
// a decoder bug related to alpha with color cache.
|
||||||
// See: https://code.google.com/p/webp/issues/detail?id=239
|
// See: https://code.google.com/p/webp/issues/detail?id=239
|
||||||
// Need to re-enable this later.
|
// Need to re-enable this later.
|
||||||
ok = (VP8LEncodeStream(&config, &picture, bw, 0 /*use_cache*/) == VP8_ENC_OK);
|
ok = VP8LEncodeStream(&config, &picture, bw, /*use_cache=*/0);
|
||||||
WebPPictureFree(&picture);
|
WebPPictureFree(&picture);
|
||||||
ok = ok && !bw->error_;
|
ok = ok && !bw->error_;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
// Author: Jyrki Alakuijala (jyrki@google.com)
|
// Author: Jyrki Alakuijala (jyrki@google.com)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "src/enc/backward_references_enc.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -17,10 +19,11 @@
|
|||||||
#include "src/dsp/dsp.h"
|
#include "src/dsp/dsp.h"
|
||||||
#include "src/dsp/lossless.h"
|
#include "src/dsp/lossless.h"
|
||||||
#include "src/dsp/lossless_common.h"
|
#include "src/dsp/lossless_common.h"
|
||||||
#include "src/enc/backward_references_enc.h"
|
|
||||||
#include "src/enc/histogram_enc.h"
|
#include "src/enc/histogram_enc.h"
|
||||||
|
#include "src/enc/vp8i_enc.h"
|
||||||
#include "src/utils/color_cache_utils.h"
|
#include "src/utils/color_cache_utils.h"
|
||||||
#include "src/utils/utils.h"
|
#include "src/utils/utils.h"
|
||||||
|
#include "src/webp/encode.h"
|
||||||
|
|
||||||
#define MIN_BLOCK_SIZE 256 // minimum block size for backward references
|
#define MIN_BLOCK_SIZE 256 // minimum block size for backward references
|
||||||
|
|
||||||
@ -255,10 +258,13 @@ static WEBP_INLINE int MaxFindCopyLength(int len) {
|
|||||||
|
|
||||||
int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
||||||
const uint32_t* const argb, int xsize, int ysize,
|
const uint32_t* const argb, int xsize, int ysize,
|
||||||
int low_effort) {
|
int low_effort, const WebPPicture* const pic,
|
||||||
|
int percent_range, int* const percent) {
|
||||||
const int size = xsize * ysize;
|
const int size = xsize * ysize;
|
||||||
const int iter_max = GetMaxItersForQuality(quality);
|
const int iter_max = GetMaxItersForQuality(quality);
|
||||||
const uint32_t window_size = GetWindowSizeForHashChain(quality, xsize);
|
const uint32_t window_size = GetWindowSizeForHashChain(quality, xsize);
|
||||||
|
int remaining_percent = percent_range;
|
||||||
|
int percent_start = *percent;
|
||||||
int pos;
|
int pos;
|
||||||
int argb_comp;
|
int argb_comp;
|
||||||
uint32_t base_position;
|
uint32_t base_position;
|
||||||
@ -276,7 +282,13 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
|||||||
|
|
||||||
hash_to_first_index =
|
hash_to_first_index =
|
||||||
(int32_t*)WebPSafeMalloc(HASH_SIZE, sizeof(*hash_to_first_index));
|
(int32_t*)WebPSafeMalloc(HASH_SIZE, sizeof(*hash_to_first_index));
|
||||||
if (hash_to_first_index == NULL) return 0;
|
if (hash_to_first_index == NULL) {
|
||||||
|
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
percent_range = remaining_percent / 2;
|
||||||
|
remaining_percent -= percent_range;
|
||||||
|
|
||||||
// Set the int32_t array to -1.
|
// Set the int32_t array to -1.
|
||||||
memset(hash_to_first_index, 0xff, HASH_SIZE * sizeof(*hash_to_first_index));
|
memset(hash_to_first_index, 0xff, HASH_SIZE * sizeof(*hash_to_first_index));
|
||||||
@ -323,12 +335,22 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
|||||||
hash_to_first_index[hash_code] = pos++;
|
hash_to_first_index[hash_code] = pos++;
|
||||||
argb_comp = argb_comp_next;
|
argb_comp = argb_comp_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!WebPReportProgress(
|
||||||
|
pic, percent_start + percent_range * pos / (size - 2), percent)) {
|
||||||
|
WebPSafeFree(hash_to_first_index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Process the penultimate pixel.
|
// Process the penultimate pixel.
|
||||||
chain[pos] = hash_to_first_index[GetPixPairHash64(argb + pos)];
|
chain[pos] = hash_to_first_index[GetPixPairHash64(argb + pos)];
|
||||||
|
|
||||||
WebPSafeFree(hash_to_first_index);
|
WebPSafeFree(hash_to_first_index);
|
||||||
|
|
||||||
|
percent_start += percent_range;
|
||||||
|
if (!WebPReportProgress(pic, percent_start, percent)) return 0;
|
||||||
|
percent_range = remaining_percent;
|
||||||
|
|
||||||
// Find the best match interval at each pixel, defined by an offset to the
|
// Find the best match interval at each pixel, defined by an offset to the
|
||||||
// pixel and a length. The right-most pixel cannot match anything to the right
|
// pixel and a length. The right-most pixel cannot match anything to the right
|
||||||
// (hence a best length of 0) and the left-most pixel nothing to the left
|
// (hence a best length of 0) and the left-most pixel nothing to the left
|
||||||
@ -417,8 +439,17 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
|||||||
max_base_position = base_position;
|
max_base_position = base_position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!WebPReportProgress(pic,
|
||||||
|
percent_start + percent_range *
|
||||||
|
(size - 2 - base_position) /
|
||||||
|
(size - 2),
|
||||||
|
percent)) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
return WebPReportProgress(pic, percent_start + percent_range, percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WEBP_INLINE void AddSingleLiteral(uint32_t pixel, int use_color_cache,
|
static WEBP_INLINE void AddSingleLiteral(uint32_t pixel, int use_color_cache,
|
||||||
@ -1006,25 +1037,31 @@ Error:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPEncodingError VP8LGetBackwardReferences(
|
int VP8LGetBackwardReferences(
|
||||||
int width, int height, const uint32_t* const argb, int quality,
|
int width, int height, const uint32_t* const argb, int quality,
|
||||||
int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
|
int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
|
||||||
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
|
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
|
||||||
int* const cache_bits_best) {
|
int* const cache_bits_best, const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent) {
|
||||||
if (low_effort) {
|
if (low_effort) {
|
||||||
VP8LBackwardRefs* refs_best;
|
VP8LBackwardRefs* refs_best;
|
||||||
*cache_bits_best = cache_bits_max;
|
*cache_bits_best = cache_bits_max;
|
||||||
refs_best = GetBackwardReferencesLowEffort(
|
refs_best = GetBackwardReferencesLowEffort(
|
||||||
width, height, argb, cache_bits_best, hash_chain, refs);
|
width, height, argb, cache_bits_best, hash_chain, refs);
|
||||||
if (refs_best == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
|
if (refs_best == NULL) {
|
||||||
|
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// Set it in first position.
|
// Set it in first position.
|
||||||
BackwardRefsSwap(refs_best, &refs[0]);
|
BackwardRefsSwap(refs_best, &refs[0]);
|
||||||
} else {
|
} else {
|
||||||
if (!GetBackwardReferences(width, height, argb, quality, lz77_types_to_try,
|
if (!GetBackwardReferences(width, height, argb, quality, lz77_types_to_try,
|
||||||
cache_bits_max, do_no_cache, hash_chain, refs,
|
cache_bits_max, do_no_cache, hash_chain, refs,
|
||||||
cache_bits_best)) {
|
cache_bits_best)) {
|
||||||
return VP8_ENC_ERROR_OUT_OF_MEMORY;
|
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VP8_ENC_OK;
|
|
||||||
|
return WebPReportProgress(pic, *percent + percent_range, percent);
|
||||||
}
|
}
|
||||||
|
@ -134,10 +134,11 @@ struct VP8LHashChain {
|
|||||||
|
|
||||||
// Must be called first, to set size.
|
// Must be called first, to set size.
|
||||||
int VP8LHashChainInit(VP8LHashChain* const p, int size);
|
int VP8LHashChainInit(VP8LHashChain* const p, int size);
|
||||||
// Pre-compute the best matches for argb.
|
// Pre-compute the best matches for argb. pic and percent are for progress.
|
||||||
int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
int VP8LHashChainFill(VP8LHashChain* const p, int quality,
|
||||||
const uint32_t* const argb, int xsize, int ysize,
|
const uint32_t* const argb, int xsize, int ysize,
|
||||||
int low_effort);
|
int low_effort, const WebPPicture* const pic,
|
||||||
|
int percent_range, int* const percent);
|
||||||
void VP8LHashChainClear(VP8LHashChain* const p); // release memory
|
void VP8LHashChainClear(VP8LHashChain* const p); // release memory
|
||||||
|
|
||||||
static WEBP_INLINE int VP8LHashChainFindOffset(const VP8LHashChain* const p,
|
static WEBP_INLINE int VP8LHashChainFindOffset(const VP8LHashChain* const p,
|
||||||
@ -227,11 +228,14 @@ enum VP8LLZ77Type {
|
|||||||
// VP8LBackwardRefs is put in the first element, the best value with no-cache in
|
// VP8LBackwardRefs is put in the first element, the best value with no-cache in
|
||||||
// the second element.
|
// the second element.
|
||||||
// In both cases, the last element is used as temporary internally.
|
// In both cases, the last element is used as temporary internally.
|
||||||
WebPEncodingError VP8LGetBackwardReferences(
|
// pic and percent are for progress.
|
||||||
|
// Returns false in case of error (stored in pic->error_code).
|
||||||
|
int VP8LGetBackwardReferences(
|
||||||
int width, int height, const uint32_t* const argb, int quality,
|
int width, int height, const uint32_t* const argb, int quality,
|
||||||
int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
|
int low_effort, int lz77_types_to_try, int cache_bits_max, int do_no_cache,
|
||||||
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
|
const VP8LHashChain* const hash_chain, VP8LBackwardRefs* const refs,
|
||||||
int* const cache_bits_best);
|
int* const cache_bits_best, const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,11 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "src/enc/backward_references_enc.h"
|
|
||||||
#include "src/enc/histogram_enc.h"
|
|
||||||
#include "src/dsp/lossless.h"
|
#include "src/dsp/lossless.h"
|
||||||
#include "src/dsp/lossless_common.h"
|
#include "src/dsp/lossless_common.h"
|
||||||
|
#include "src/enc/backward_references_enc.h"
|
||||||
|
#include "src/enc/histogram_enc.h"
|
||||||
|
#include "src/enc/vp8i_enc.h"
|
||||||
#include "src/utils/utils.h"
|
#include "src/utils/utils.h"
|
||||||
|
|
||||||
#define MAX_BIT_COST 1.e38
|
#define MAX_BIT_COST 1.e38
|
||||||
@ -1169,13 +1170,13 @@ static void RemoveEmptyHistograms(VP8LHistogramSet* const image_histo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||||
const VP8LBackwardRefs* const refs,
|
const VP8LBackwardRefs* const refs, int quality,
|
||||||
int quality, int low_effort,
|
int low_effort, int histogram_bits, int cache_bits,
|
||||||
int histogram_bits, int cache_bits,
|
|
||||||
VP8LHistogramSet* const image_histo,
|
VP8LHistogramSet* const image_histo,
|
||||||
VP8LHistogram* const tmp_histo,
|
VP8LHistogram* const tmp_histo,
|
||||||
uint16_t* const histogram_symbols) {
|
uint16_t* const histogram_symbols,
|
||||||
int ok = 0;
|
const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent) {
|
||||||
const int histo_xsize =
|
const int histo_xsize =
|
||||||
histogram_bits ? VP8LSubSampleSize(xsize, histogram_bits) : 1;
|
histogram_bits ? VP8LSubSampleSize(xsize, histogram_bits) : 1;
|
||||||
const int histo_ysize =
|
const int histo_ysize =
|
||||||
@ -1192,7 +1193,10 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
WebPSafeMalloc(2 * image_histo_raw_size, sizeof(map_tmp));
|
WebPSafeMalloc(2 * image_histo_raw_size, sizeof(map_tmp));
|
||||||
uint16_t* const cluster_mappings = map_tmp + image_histo_raw_size;
|
uint16_t* const cluster_mappings = map_tmp + image_histo_raw_size;
|
||||||
int num_used = image_histo_raw_size;
|
int num_used = image_histo_raw_size;
|
||||||
if (orig_histo == NULL || map_tmp == NULL) goto Error;
|
if (orig_histo == NULL || map_tmp == NULL) {
|
||||||
|
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the histograms from backward references.
|
// Construct the histograms from backward references.
|
||||||
HistogramBuild(xsize, histogram_bits, refs, orig_histo);
|
HistogramBuild(xsize, histogram_bits, refs, orig_histo);
|
||||||
@ -1212,10 +1216,9 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
|
|
||||||
HistogramAnalyzeEntropyBin(image_histo, bin_map, low_effort);
|
HistogramAnalyzeEntropyBin(image_histo, bin_map, low_effort);
|
||||||
// Collapse histograms with similar entropy.
|
// Collapse histograms with similar entropy.
|
||||||
HistogramCombineEntropyBin(image_histo, &num_used, histogram_symbols,
|
HistogramCombineEntropyBin(
|
||||||
cluster_mappings, tmp_histo, bin_map,
|
image_histo, &num_used, histogram_symbols, cluster_mappings, tmp_histo,
|
||||||
entropy_combine_num_bins, combine_cost_factor,
|
bin_map, entropy_combine_num_bins, combine_cost_factor, low_effort);
|
||||||
low_effort);
|
|
||||||
OptimizeHistogramSymbols(image_histo, cluster_mappings, num_clusters,
|
OptimizeHistogramSymbols(image_histo, cluster_mappings, num_clusters,
|
||||||
map_tmp, histogram_symbols);
|
map_tmp, histogram_symbols);
|
||||||
}
|
}
|
||||||
@ -1229,11 +1232,13 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
int do_greedy;
|
int do_greedy;
|
||||||
if (!HistogramCombineStochastic(image_histo, &num_used, threshold_size,
|
if (!HistogramCombineStochastic(image_histo, &num_used, threshold_size,
|
||||||
&do_greedy)) {
|
&do_greedy)) {
|
||||||
|
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
if (do_greedy) {
|
if (do_greedy) {
|
||||||
RemoveEmptyHistograms(image_histo);
|
RemoveEmptyHistograms(image_histo);
|
||||||
if (!HistogramCombineGreedy(image_histo, &num_used)) {
|
if (!HistogramCombineGreedy(image_histo, &num_used)) {
|
||||||
|
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1243,10 +1248,12 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
RemoveEmptyHistograms(image_histo);
|
RemoveEmptyHistograms(image_histo);
|
||||||
HistogramRemap(orig_histo, image_histo, histogram_symbols);
|
HistogramRemap(orig_histo, image_histo, histogram_symbols);
|
||||||
|
|
||||||
ok = 1;
|
if (!WebPReportProgress(pic, *percent + percent_range, percent)) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
VP8LFreeHistogramSet(orig_histo);
|
VP8LFreeHistogramSet(orig_histo);
|
||||||
WebPSafeFree(map_tmp);
|
WebPSafeFree(map_tmp);
|
||||||
return ok;
|
return (pic->error_code == VP8_ENC_OK);
|
||||||
}
|
}
|
||||||
|
@ -105,14 +105,16 @@ static WEBP_INLINE int VP8LHistogramNumCodes(int palette_code_bits) {
|
|||||||
((palette_code_bits > 0) ? (1 << palette_code_bits) : 0);
|
((palette_code_bits > 0) ? (1 << palette_code_bits) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builds the histogram image.
|
// Builds the histogram image. pic and percent are for progress.
|
||||||
|
// Returns false in case of error (stored in pic->error_code).
|
||||||
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||||
const VP8LBackwardRefs* const refs,
|
const VP8LBackwardRefs* const refs, int quality,
|
||||||
int quality, int low_effort,
|
int low_effort, int histogram_bits, int cache_bits,
|
||||||
int histogram_bits, int cache_bits,
|
|
||||||
VP8LHistogramSet* const image_histo,
|
VP8LHistogramSet* const image_histo,
|
||||||
VP8LHistogram* const tmp_histo,
|
VP8LHistogram* const tmp_histo,
|
||||||
uint16_t* const histogram_symbols);
|
uint16_t* const histogram_symbols,
|
||||||
|
const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent);
|
||||||
|
|
||||||
// Returns the entropy for the symbols in the input array.
|
// Returns the entropy for the symbols in the input array.
|
||||||
double VP8LBitsEntropy(const uint32_t* const array, int n);
|
double VP8LBitsEntropy(const uint32_t* const array, int n);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "src/dsp/lossless.h"
|
#include "src/dsp/lossless.h"
|
||||||
#include "src/dsp/lossless_common.h"
|
#include "src/dsp/lossless_common.h"
|
||||||
|
#include "src/enc/vp8i_enc.h"
|
||||||
#include "src/enc/vp8li_enc.h"
|
#include "src/enc/vp8li_enc.h"
|
||||||
|
|
||||||
#define MAX_DIFF_COST (1e30f)
|
#define MAX_DIFF_COST (1e30f)
|
||||||
@ -472,12 +473,15 @@ static void CopyImageWithPrediction(int width, int height,
|
|||||||
// with respect to predictions. If near_lossless_quality < 100, applies
|
// with respect to predictions. If near_lossless_quality < 100, applies
|
||||||
// near lossless processing, shaving off more bits of residuals for lower
|
// near lossless processing, shaving off more bits of residuals for lower
|
||||||
// qualities.
|
// qualities.
|
||||||
void VP8LResidualImage(int width, int height, int bits, int low_effort,
|
int VP8LResidualImage(int width, int height, int bits, int low_effort,
|
||||||
uint32_t* const argb, uint32_t* const argb_scratch,
|
uint32_t* const argb, uint32_t* const argb_scratch,
|
||||||
uint32_t* const image, int near_lossless_quality,
|
uint32_t* const image, int near_lossless_quality,
|
||||||
int exact, int used_subtract_green) {
|
int exact, int used_subtract_green,
|
||||||
|
const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent) {
|
||||||
const int tiles_per_row = VP8LSubSampleSize(width, bits);
|
const int tiles_per_row = VP8LSubSampleSize(width, bits);
|
||||||
const int tiles_per_col = VP8LSubSampleSize(height, bits);
|
const int tiles_per_col = VP8LSubSampleSize(height, bits);
|
||||||
|
int percent_start = *percent;
|
||||||
int tile_y;
|
int tile_y;
|
||||||
int histo[4][256];
|
int histo[4][256];
|
||||||
const int max_quantization = 1 << VP8LNearLosslessBits(near_lossless_quality);
|
const int max_quantization = 1 << VP8LNearLosslessBits(near_lossless_quality);
|
||||||
@ -491,17 +495,24 @@ void VP8LResidualImage(int width, int height, int bits, int low_effort,
|
|||||||
for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
|
for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
|
||||||
int tile_x;
|
int tile_x;
|
||||||
for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
|
for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
|
||||||
const int pred = GetBestPredictorForTile(width, height, tile_x, tile_y,
|
const int pred = GetBestPredictorForTile(
|
||||||
bits, histo, argb_scratch, argb, max_quantization, exact,
|
width, height, tile_x, tile_y, bits, histo, argb_scratch, argb,
|
||||||
used_subtract_green, image);
|
max_quantization, exact, used_subtract_green, image);
|
||||||
image[tile_y * tiles_per_row + tile_x] = ARGB_BLACK | (pred << 8);
|
image[tile_y * tiles_per_row + tile_x] = ARGB_BLACK | (pred << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!WebPReportProgress(
|
||||||
|
pic, percent_start + percent_range * tile_y / tiles_per_col,
|
||||||
|
percent)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyImageWithPrediction(width, height, bits, image, argb_scratch, argb,
|
CopyImageWithPrediction(width, height, bits, image, argb_scratch, argb,
|
||||||
low_effort, max_quantization, exact,
|
low_effort, max_quantization, exact,
|
||||||
used_subtract_green);
|
used_subtract_green);
|
||||||
|
return WebPReportProgress(pic, percent_start + percent_range, percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -714,11 +725,14 @@ static void CopyTileWithColorTransform(int xsize, int ysize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
|
int VP8LColorSpaceTransform(int width, int height, int bits, int quality,
|
||||||
uint32_t* const argb, uint32_t* image) {
|
uint32_t* const argb, uint32_t* image,
|
||||||
|
const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent) {
|
||||||
const int max_tile_size = 1 << bits;
|
const int max_tile_size = 1 << bits;
|
||||||
const int tile_xsize = VP8LSubSampleSize(width, bits);
|
const int tile_xsize = VP8LSubSampleSize(width, bits);
|
||||||
const int tile_ysize = VP8LSubSampleSize(height, bits);
|
const int tile_ysize = VP8LSubSampleSize(height, bits);
|
||||||
|
int percent_start = *percent;
|
||||||
int accumulated_red_histo[256] = { 0 };
|
int accumulated_red_histo[256] = { 0 };
|
||||||
int accumulated_blue_histo[256] = { 0 };
|
int accumulated_blue_histo[256] = { 0 };
|
||||||
int tile_x, tile_y;
|
int tile_x, tile_y;
|
||||||
@ -768,5 +782,11 @@ void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!WebPReportProgress(
|
||||||
|
pic, percent_start + percent_range * tile_y / tile_ysize,
|
||||||
|
percent)) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -89,9 +89,10 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
|||||||
|
|
||||||
// Encodes the main image stream using the supplied bit writer.
|
// Encodes the main image stream using the supplied bit writer.
|
||||||
// If 'use_cache' is false, disables the use of color cache.
|
// If 'use_cache' is false, disables the use of color cache.
|
||||||
WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
|
// Returns false in case of error (stored in picture->error_code).
|
||||||
const WebPPicture* const picture,
|
int VP8LEncodeStream(const WebPConfig* const config,
|
||||||
VP8LBitWriter* const bw, int use_cache);
|
const WebPPicture* const picture, VP8LBitWriter* const bw,
|
||||||
|
int use_cache);
|
||||||
|
|
||||||
#if (WEBP_NEAR_LOSSLESS == 1)
|
#if (WEBP_NEAR_LOSSLESS == 1)
|
||||||
// in near_lossless.c
|
// in near_lossless.c
|
||||||
@ -103,13 +104,18 @@ int VP8ApplyNearLossless(const WebPPicture* const picture, int quality,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Image transforms in predictor.c.
|
// Image transforms in predictor.c.
|
||||||
|
|
||||||
void VP8LResidualImage(int width, int height, int bits, int low_effort,
|
// pic and percent are for progress.
|
||||||
|
// Returns false in case of error (stored in pic->error_code).
|
||||||
|
int VP8LResidualImage(int width, int height, int bits, int low_effort,
|
||||||
uint32_t* const argb, uint32_t* const argb_scratch,
|
uint32_t* const argb, uint32_t* const argb_scratch,
|
||||||
uint32_t* const image, int near_lossless, int exact,
|
uint32_t* const image, int near_lossless, int exact,
|
||||||
int used_subtract_green);
|
int used_subtract_green, const WebPPicture* const pic,
|
||||||
|
int percent_range, int* const percent);
|
||||||
|
|
||||||
void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
|
int VP8LColorSpaceTransform(int width, int height, int bits, int quality,
|
||||||
uint32_t* const argb, uint32_t* image);
|
uint32_t* const argb, uint32_t* image,
|
||||||
|
const WebPPicture* const pic, int percent_range,
|
||||||
|
int* const percent);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture,
|
|||||||
// the original dimension will be lost). Picture 'dst' need not be initialized
|
// the original dimension will be lost). Picture 'dst' need not be initialized
|
||||||
// with WebPPictureInit() if it is different from 'src', since its content will
|
// with WebPPictureInit() if it is different from 'src', since its content will
|
||||||
// be overwritten.
|
// be overwritten.
|
||||||
// Returns false in case of memory allocation error or invalid parameters.
|
// Returns false in case of invalid parameters.
|
||||||
WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
|
WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
|
||||||
int left, int top, int width, int height,
|
int left, int top, int width, int height,
|
||||||
WebPPicture* dst);
|
WebPPicture* dst);
|
||||||
|
Loading…
Reference in New Issue
Block a user