mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-19 20:08:28 +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");
|
if (stats->lossless_features & 8) fprintf(stderr, " PALETTE");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
fprintf(stderr, " * Precision Bits: histogram=%d transform=%d cache=%d\n",
|
fprintf(stderr, " * Precision Bits: histogram=%d", stats->histogram_bits);
|
||||||
stats->histogram_bits, stats->transform_bits, stats->cache_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) {
|
if (stats->palette_size > 0) {
|
||||||
fprintf(stderr, " * Palette size: %d\n", stats->palette_size);
|
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->lossless_features = best.stats.lossless_features;
|
||||||
stats->histogram_bits = best.stats.histogram_bits;
|
stats->histogram_bits = best.stats.histogram_bits;
|
||||||
stats->transform_bits = best.stats.transform_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->cache_bits = best.stats.cache_bits;
|
||||||
stats->palette_size = best.stats.palette_size;
|
stats->palette_size = best.stats.palette_size;
|
||||||
stats->lossless_size = best.stats.lossless_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 method = config->method;
|
||||||
const int low_effort = (config->method == 0);
|
const int low_effort = (config->method == 0);
|
||||||
int i;
|
int i;
|
||||||
int use_palette;
|
int use_palette, transform_bits;
|
||||||
int n_lz77s;
|
int n_lz77s;
|
||||||
// If set to 0, analyze the cache with the computed cache value. If 1, also
|
// If set to 0, analyze the cache with the computed cache value. If 1, also
|
||||||
// analyze with no-cache.
|
// analyze with no-cache.
|
||||||
@ -298,7 +298,9 @@ static int EncoderAnalyze(VP8LEncoder* const enc,
|
|||||||
// Empirical bit sizes.
|
// Empirical bit sizes.
|
||||||
enc->histo_bits_ = GetHistoBits(method, use_palette,
|
enc->histo_bits_ = GetHistoBits(method, use_palette,
|
||||||
pic->width, pic->height);
|
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) {
|
if (low_effort) {
|
||||||
// AnalyzeEntropy is somewhat slow.
|
// AnalyzeEntropy is somewhat slow.
|
||||||
@ -312,8 +314,8 @@ static int EncoderAnalyze(VP8LEncoder* const enc,
|
|||||||
// Try out multiple LZ77 on images with few colors.
|
// Try out multiple LZ77 on images with few colors.
|
||||||
n_lz77s = (enc->palette_size_ > 0 && enc->palette_size_ <= 16) ? 2 : 1;
|
n_lz77s = (enc->palette_size_ > 0 && enc->palette_size_ <= 16) ? 2 : 1;
|
||||||
if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride, use_palette,
|
if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride, use_palette,
|
||||||
enc->palette_size_, enc->transform_bits_,
|
enc->palette_size_, transform_bits, &min_entropy_ix,
|
||||||
&min_entropy_ix, red_and_blue_always_zero)) {
|
red_and_blue_always_zero)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (method == 6 && config->quality == 100) {
|
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 quality, int low_effort,
|
||||||
int used_subtract_green, VP8LBitWriter* const bw,
|
int used_subtract_green, VP8LBitWriter* const bw,
|
||||||
int percent_range, int* const percent) {
|
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_width = VP8LSubSampleSize(width, pred_bits);
|
||||||
const int transform_height = VP8LSubSampleSize(height, pred_bits);
|
const int transform_height = VP8LSubSampleSize(height, pred_bits);
|
||||||
// we disable near-lossless quantization if palette is used.
|
// we disable near-lossless quantization if palette is used.
|
||||||
@ -1093,11 +1095,11 @@ static int ApplyPredictFilter(VP8LEncoder* const enc, int width, int height,
|
|||||||
percent);
|
percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ApplyCrossColorFilter(const VP8LEncoder* const enc, int width,
|
static int ApplyCrossColorFilter(VP8LEncoder* const enc, int width, int height,
|
||||||
int height, int quality, int low_effort,
|
int quality, int low_effort,
|
||||||
VP8LBitWriter* const bw, int percent_range,
|
VP8LBitWriter* const bw, int percent_range,
|
||||||
int* const percent) {
|
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_width = VP8LSubSampleSize(width, ccolor_transform_bits);
|
||||||
const int transform_height = VP8LSubSampleSize(height, 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) /
|
enc->use_predict_ ? (width + 1) * 2 + (width * 2 + sizeof(uint32_t) - 1) /
|
||||||
sizeof(uint32_t)
|
sizeof(uint32_t)
|
||||||
: 0;
|
: 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 =
|
const uint64_t transform_data_size =
|
||||||
(enc->use_predict_ || enc->use_cross_color_)
|
(enc->use_predict_ || enc->use_cross_color_)
|
||||||
? (uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) *
|
? (uint64_t)VP8LSubSampleSize(width, min_transform_bits) *
|
||||||
VP8LSubSampleSize(height, enc->transform_bits_)
|
VP8LSubSampleSize(height, min_transform_bits)
|
||||||
: 0;
|
: 0;
|
||||||
const uint64_t max_alignment_in_words =
|
const uint64_t max_alignment_in_words =
|
||||||
(WEBP_ALIGN_CST + sizeof(uint32_t) - 1) / sizeof(uint32_t);
|
(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_subtract_green_) stats->lossless_features |= 4;
|
||||||
if (enc->use_palette_) stats->lossless_features |= 8;
|
if (enc->use_palette_) stats->lossless_features |= 8;
|
||||||
stats->histogram_bits = enc->histo_bits_;
|
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->cache_bits = enc->cache_bits_;
|
||||||
stats->palette_size = enc->palette_size_;
|
stats->palette_size = enc->palette_size_;
|
||||||
stats->lossless_size = (int)(best_size - byte_position);
|
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.
|
// Copy the values that were computed for the main encoder.
|
||||||
enc_side->histo_bits_ = enc_main->histo_bits_;
|
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_;
|
enc_side->palette_size_ = enc_main->palette_size_;
|
||||||
memcpy(enc_side->palette_, enc_main->palette_,
|
memcpy(enc_side->palette_, enc_main->palette_,
|
||||||
sizeof(enc_main->palette_));
|
sizeof(enc_main->palette_));
|
||||||
|
@ -59,7 +59,8 @@ typedef struct {
|
|||||||
|
|
||||||
// Encoding parameters derived from quality parameter.
|
// Encoding parameters derived from quality parameter.
|
||||||
int histo_bits_;
|
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.
|
int cache_bits_; // If equal to 0, don't use color cache.
|
||||||
|
|
||||||
// Encoding parameters derived from image characteristics.
|
// Encoding parameters derived from image characteristics.
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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++,
|
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
|
||||||
// the types are left here for reference.
|
// the types are left here for reference.
|
||||||
@ -224,14 +224,15 @@ struct WebPAuxStats {
|
|||||||
uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
|
uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
|
||||||
// bit2:subtract-green bit3:color indexing
|
// bit2:subtract-green bit3:color indexing
|
||||||
int histogram_bits; // number of precision bits of histogram
|
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 cache_bits; // number of bits for color cache lookup
|
||||||
int palette_size; // number of color in palette, if used
|
int palette_size; // number of color in palette, if used
|
||||||
int lossless_size; // final lossless size
|
int lossless_size; // final lossless size
|
||||||
int lossless_hdr_size; // lossless header (transform, huffman etc) size
|
int lossless_hdr_size; // lossless header (transform, huffman etc) size
|
||||||
int lossless_data_size; // lossless image data 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.
|
// Signature for output function. Should return true if writing was successful.
|
||||||
|
Loading…
Reference in New Issue
Block a user