mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-25 13:18:22 +01:00
Allow transform_bits to be different during encoding.
The spec allows it but it is currently forced to the same value for simplicity. Change-Id: I26197dbf3342f7a72115cc7f7805c154313a2afb
This commit is contained in:
parent
1e462ca80e
commit
1bf198a22b
@ -178,8 +178,14 @@ static void PrintFullLosslessInfo(const WebPAuxStats* const stats,
|
||||
if (stats->lossless_features & 8) fprintf(stderr, " PALETTE");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
fprintf(stderr, " * Precision Bits: histogram=%d transform=%d cache=%d\n",
|
||||
stats->histogram_bits, stats->transform_bits, stats->cache_bits);
|
||||
fprintf(stderr, " * Precision Bits: histogram=%d", stats->histogram_bits);
|
||||
if (stats->lossless_features & 1) {
|
||||
fprintf(stderr, " prediction=%d", stats->transform_bits);
|
||||
}
|
||||
if (stats->lossless_features & 2) {
|
||||
fprintf(stderr, " cross-color=%d", stats->cross_color_transform_bits);
|
||||
}
|
||||
fprintf(stderr, " cache=%d\n", stats->cache_bits);
|
||||
if (stats->palette_size > 0) {
|
||||
fprintf(stderr, " * Palette size: %d\n", stats->palette_size);
|
||||
}
|
||||
|
@ -276,6 +276,7 @@ static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height,
|
||||
stats->lossless_features = best.stats.lossless_features;
|
||||
stats->histogram_bits = best.stats.histogram_bits;
|
||||
stats->transform_bits = best.stats.transform_bits;
|
||||
stats->cross_color_transform_bits = best.stats.cross_color_transform_bits;
|
||||
stats->cache_bits = best.stats.cache_bits;
|
||||
stats->palette_size = best.stats.palette_size;
|
||||
stats->lossless_size = best.stats.lossless_size;
|
||||
|
@ -281,7 +281,7 @@ static int EncoderAnalyze(VP8LEncoder* const enc,
|
||||
const int method = config->method;
|
||||
const int low_effort = (config->method == 0);
|
||||
int i;
|
||||
int use_palette;
|
||||
int use_palette, transform_bits;
|
||||
int n_lz77s;
|
||||
// If set to 0, analyze the cache with the computed cache value. If 1, also
|
||||
// analyze with no-cache.
|
||||
@ -298,7 +298,9 @@ static int EncoderAnalyze(VP8LEncoder* const enc,
|
||||
// Empirical bit sizes.
|
||||
enc->histo_bits_ = GetHistoBits(method, use_palette,
|
||||
pic->width, pic->height);
|
||||
enc->transform_bits_ = GetTransformBits(method, enc->histo_bits_);
|
||||
transform_bits = GetTransformBits(method, enc->histo_bits_);
|
||||
enc->predictor_transform_bits_ = transform_bits;
|
||||
enc->cross_color_transform_bits_ = transform_bits;
|
||||
|
||||
if (low_effort) {
|
||||
// AnalyzeEntropy is somewhat slow.
|
||||
@ -312,8 +314,8 @@ static int EncoderAnalyze(VP8LEncoder* const enc,
|
||||
// Try out multiple LZ77 on images with few colors.
|
||||
n_lz77s = (enc->palette_size_ > 0 && enc->palette_size_ <= 16) ? 2 : 1;
|
||||
if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride, use_palette,
|
||||
enc->palette_size_, enc->transform_bits_,
|
||||
&min_entropy_ix, red_and_blue_always_zero)) {
|
||||
enc->palette_size_, transform_bits, &min_entropy_ix,
|
||||
red_and_blue_always_zero)) {
|
||||
return 0;
|
||||
}
|
||||
if (method == 6 && config->quality == 100) {
|
||||
@ -1069,7 +1071,7 @@ static int ApplyPredictFilter(VP8LEncoder* const enc, int width, int height,
|
||||
int quality, int low_effort,
|
||||
int used_subtract_green, VP8LBitWriter* const bw,
|
||||
int percent_range, int* const percent) {
|
||||
const int pred_bits = enc->transform_bits_;
|
||||
const int pred_bits = enc->predictor_transform_bits_;
|
||||
const int transform_width = VP8LSubSampleSize(width, pred_bits);
|
||||
const int transform_height = VP8LSubSampleSize(height, pred_bits);
|
||||
// we disable near-lossless quantization if palette is used.
|
||||
@ -1093,11 +1095,11 @@ static int ApplyPredictFilter(VP8LEncoder* const enc, int width, int height,
|
||||
percent);
|
||||
}
|
||||
|
||||
static int ApplyCrossColorFilter(const VP8LEncoder* const enc, int width,
|
||||
int height, int quality, int low_effort,
|
||||
static int ApplyCrossColorFilter(VP8LEncoder* const enc, int width, int height,
|
||||
int quality, int low_effort,
|
||||
VP8LBitWriter* const bw, int percent_range,
|
||||
int* const percent) {
|
||||
const int ccolor_transform_bits = enc->transform_bits_;
|
||||
const int ccolor_transform_bits = enc->cross_color_transform_bits_;
|
||||
const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
|
||||
const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
|
||||
|
||||
@ -1200,10 +1202,14 @@ static int AllocateTransformBuffer(VP8LEncoder* const enc, int width,
|
||||
enc->use_predict_ ? (width + 1) * 2 + (width * 2 + sizeof(uint32_t) - 1) /
|
||||
sizeof(uint32_t)
|
||||
: 0;
|
||||
const int min_transform_bits =
|
||||
(enc->predictor_transform_bits_ < enc->cross_color_transform_bits_)
|
||||
? enc->predictor_transform_bits_
|
||||
: enc->cross_color_transform_bits_;
|
||||
const uint64_t transform_data_size =
|
||||
(enc->use_predict_ || enc->use_cross_color_)
|
||||
? (uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) *
|
||||
VP8LSubSampleSize(height, enc->transform_bits_)
|
||||
? (uint64_t)VP8LSubSampleSize(width, min_transform_bits) *
|
||||
VP8LSubSampleSize(height, min_transform_bits)
|
||||
: 0;
|
||||
const uint64_t max_alignment_in_words =
|
||||
(WEBP_ALIGN_CST + sizeof(uint32_t) - 1) / sizeof(uint32_t);
|
||||
@ -1628,7 +1634,8 @@ static int EncodeStreamHook(void* input, void* data2) {
|
||||
if (enc->use_subtract_green_) stats->lossless_features |= 4;
|
||||
if (enc->use_palette_) stats->lossless_features |= 8;
|
||||
stats->histogram_bits = enc->histo_bits_;
|
||||
stats->transform_bits = enc->transform_bits_;
|
||||
stats->transform_bits = enc->predictor_transform_bits_;
|
||||
stats->cross_color_transform_bits = enc->cross_color_transform_bits_;
|
||||
stats->cache_bits = enc->cache_bits_;
|
||||
stats->palette_size = enc->palette_size_;
|
||||
stats->lossless_size = (int)(best_size - byte_position);
|
||||
@ -1738,7 +1745,10 @@ int VP8LEncodeStream(const WebPConfig* const config,
|
||||
}
|
||||
// Copy the values that were computed for the main encoder.
|
||||
enc_side->histo_bits_ = enc_main->histo_bits_;
|
||||
enc_side->transform_bits_ = enc_main->transform_bits_;
|
||||
enc_side->predictor_transform_bits_ =
|
||||
enc_main->predictor_transform_bits_;
|
||||
enc_side->cross_color_transform_bits_ =
|
||||
enc_main->cross_color_transform_bits_;
|
||||
enc_side->palette_size_ = enc_main->palette_size_;
|
||||
memcpy(enc_side->palette_, enc_main->palette_,
|
||||
sizeof(enc_main->palette_));
|
||||
|
@ -59,7 +59,8 @@ typedef struct {
|
||||
|
||||
// Encoding parameters derived from quality parameter.
|
||||
int histo_bits_;
|
||||
int transform_bits_; // <= MAX_TRANSFORM_BITS.
|
||||
int predictor_transform_bits_; // <= MAX_TRANSFORM_BITS
|
||||
int cross_color_transform_bits_; // <= MAX_TRANSFORM_BITS
|
||||
int cache_bits_; // If equal to 0, don't use color cache.
|
||||
|
||||
// Encoding parameters derived from image characteristics.
|
||||
|
@ -20,7 +20,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x020f // MAJOR(8b) + MINOR(8b)
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x0210 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
|
||||
// the types are left here for reference.
|
||||
@ -224,14 +224,15 @@ struct WebPAuxStats {
|
||||
uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
|
||||
// bit2:subtract-green bit3:color indexing
|
||||
int histogram_bits; // number of precision bits of histogram
|
||||
int transform_bits; // precision bits for transform
|
||||
int transform_bits; // precision bits for predictor transform
|
||||
int cache_bits; // number of bits for color cache lookup
|
||||
int palette_size; // number of color in palette, if used
|
||||
int lossless_size; // final lossless size
|
||||
int lossless_hdr_size; // lossless header (transform, huffman etc) size
|
||||
int lossless_data_size; // lossless image data size
|
||||
int cross_color_transform_bits; // precision bits for cross-color transform
|
||||
|
||||
uint32_t pad[2]; // padding for later use
|
||||
uint32_t pad[1]; // padding for later use
|
||||
};
|
||||
|
||||
// Signature for output function. Should return true if writing was successful.
|
||||
|
Loading…
Reference in New Issue
Block a user