mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
Merge "rationalize use of color-cache" into 0.2.0
This commit is contained in:
commit
f1edf62fae
@ -256,8 +256,10 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
|||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
|
|
||||||
if (hash_chain == NULL) return 0;
|
if (hash_chain == NULL) return 0;
|
||||||
|
if (use_color_cache) {
|
||||||
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
if (!cc_init) goto Error;
|
if (!cc_init) goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
if (!HashChainInit(hash_chain, pix_count)) goto Error;
|
if (!HashChainInit(hash_chain, pix_count)) goto Error;
|
||||||
|
|
||||||
@ -289,15 +291,16 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
|||||||
HashChainFindCopy(hash_chain, quality,
|
HashChainFindCopy(hash_chain, quality,
|
||||||
i + 1, xsize, argb, maxlen, &offset2, &len2);
|
i + 1, xsize, argb, maxlen, &offset2, &len2);
|
||||||
if (len2 > len + 1) {
|
if (len2 > len + 1) {
|
||||||
|
const uint32_t pixel = argb[i];
|
||||||
// Alternative#2 is a better match. So push pixel at 'i' as literal.
|
// Alternative#2 is a better match. So push pixel at 'i' as literal.
|
||||||
if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) {
|
if (use_color_cache && VP8LColorCacheContains(&hashers, pixel)) {
|
||||||
const int ix = VP8LColorCacheGetIndex(&hashers, argb[i]);
|
const int ix = VP8LColorCacheGetIndex(&hashers, pixel);
|
||||||
refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
|
refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
|
||||||
} else {
|
} else {
|
||||||
refs->refs[refs->size] = PixOrCopyCreateLiteral(argb[i]);
|
refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel);
|
||||||
}
|
}
|
||||||
++refs->size;
|
++refs->size;
|
||||||
VP8LColorCacheInsert(&hashers, argb[i]);
|
if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
|
||||||
i++; // Backward reference to be done for next pixel.
|
i++; // Backward reference to be done for next pixel.
|
||||||
len = len2;
|
len = len2;
|
||||||
offset = offset2;
|
offset = offset2;
|
||||||
@ -307,24 +310,30 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
|||||||
len = MAX_LENGTH - 1;
|
len = MAX_LENGTH - 1;
|
||||||
}
|
}
|
||||||
refs->refs[refs->size++] = PixOrCopyCreateCopy(offset, len);
|
refs->refs[refs->size++] = PixOrCopyCreateCopy(offset, len);
|
||||||
|
if (use_color_cache) {
|
||||||
for (k = 0; k < len; ++k) {
|
for (k = 0; k < len; ++k) {
|
||||||
VP8LColorCacheInsert(&hashers, argb[i + k]);
|
VP8LColorCacheInsert(&hashers, argb[i + k]);
|
||||||
if (k != 0 && i + k + 1 < pix_count) {
|
}
|
||||||
|
}
|
||||||
// Add to the hash_chain (but cannot add the last pixel).
|
// Add to the hash_chain (but cannot add the last pixel).
|
||||||
|
{
|
||||||
|
const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i;
|
||||||
|
for (k = 1; k < last; ++k) {
|
||||||
HashChainInsert(hash_chain, &argb[i + k], i + k);
|
HashChainInsert(hash_chain, &argb[i + k], i + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i += len;
|
i += len;
|
||||||
} else {
|
} else {
|
||||||
if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) {
|
const uint32_t pixel = argb[i];
|
||||||
|
if (use_color_cache && VP8LColorCacheContains(&hashers, pixel)) {
|
||||||
// push pixel as a PixOrCopyCreateCacheIdx pixel
|
// push pixel as a PixOrCopyCreateCacheIdx pixel
|
||||||
int ix = VP8LColorCacheGetIndex(&hashers, argb[i]);
|
const int ix = VP8LColorCacheGetIndex(&hashers, pixel);
|
||||||
refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
|
refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
|
||||||
} else {
|
} else {
|
||||||
refs->refs[refs->size] = PixOrCopyCreateLiteral(argb[i]);
|
refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel);
|
||||||
}
|
}
|
||||||
++refs->size;
|
++refs->size;
|
||||||
VP8LColorCacheInsert(&hashers, argb[i]);
|
if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
|
||||||
if (i + 1 < pix_count) {
|
if (i + 1 < pix_count) {
|
||||||
HashChainInsert(hash_chain, &argb[i], i);
|
HashChainInsert(hash_chain, &argb[i], i);
|
||||||
}
|
}
|
||||||
@ -437,8 +446,12 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
|
|
||||||
if (cost == NULL || cost_model == NULL || hash_chain == NULL) goto Error;
|
if (cost == NULL || cost_model == NULL || hash_chain == NULL) goto Error;
|
||||||
|
|
||||||
|
if (!HashChainInit(hash_chain, pix_count)) goto Error;
|
||||||
|
|
||||||
|
if (use_color_cache) {
|
||||||
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
if (!cc_init || !HashChainInit(hash_chain, pix_count)) goto Error;
|
if (!cc_init) goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CostModelBuild(cost_model, xsize, ysize, recursive_cost_model, argb,
|
if (!CostModelBuild(cost_model, xsize, ysize, recursive_cost_model, argb,
|
||||||
cache_bits)) {
|
cache_bits)) {
|
||||||
@ -486,14 +499,20 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
// Long copy for short distances, let's skip the middle
|
// Long copy for short distances, let's skip the middle
|
||||||
// lookups for better copies.
|
// lookups for better copies.
|
||||||
// 1) insert the hashes.
|
// 1) insert the hashes.
|
||||||
|
if (use_color_cache) {
|
||||||
for (k = 0; k < len; ++k) {
|
for (k = 0; k < len; ++k) {
|
||||||
VP8LColorCacheInsert(&hashers, argb[i + k]);
|
VP8LColorCacheInsert(&hashers, argb[i + k]);
|
||||||
if (i + k + 1 < pix_count) {
|
}
|
||||||
// Add to the hash_chain (but cannot add the last pixel).
|
}
|
||||||
|
// 2) Add to the hash_chain (but cannot add the last pixel)
|
||||||
|
{
|
||||||
|
const int last = (len < pix_count - 1 - i) ? len
|
||||||
|
: pix_count - 1 - i;
|
||||||
|
for (k = 0; k < last; ++k) {
|
||||||
HashChainInsert(hash_chain, &argb[i + k], i + k);
|
HashChainInsert(hash_chain, &argb[i + k], i + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2) jump.
|
// 3) jump.
|
||||||
i += len - 1; // for loop does ++i, thus -1 here.
|
i += len - 1; // for loop does ++i, thus -1 here.
|
||||||
goto next_symbol;
|
goto next_symbol;
|
||||||
}
|
}
|
||||||
@ -515,7 +534,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
cost[i] = cost_val;
|
cost[i] = cost_val;
|
||||||
dist_array[i] = 1; // only one is inserted.
|
dist_array[i] = 1; // only one is inserted.
|
||||||
}
|
}
|
||||||
VP8LColorCacheInsert(&hashers, argb[i]);
|
if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
||||||
}
|
}
|
||||||
next_symbol: ;
|
next_symbol: ;
|
||||||
}
|
}
|
||||||
@ -574,11 +593,13 @@ static int BackwardReferencesHashChainFollowChosenPath(
|
|||||||
HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
|
HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
|
||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
|
|
||||||
if (hash_chain == NULL ||
|
if (hash_chain == NULL || !HashChainInit(hash_chain, pix_count)) {
|
||||||
!(cc_init = VP8LColorCacheInit(&hashers, cache_bits)) ||
|
|
||||||
!HashChainInit(hash_chain, pix_count)) {
|
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
if (use_color_cache) {
|
||||||
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
|
if (!cc_init) goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
refs->size = 0;
|
refs->size = 0;
|
||||||
for (ix = 0; ix < chosen_path_size; ++ix, ++size) {
|
for (ix = 0; ix < chosen_path_size; ++ix, ++size) {
|
||||||
@ -590,10 +611,14 @@ static int BackwardReferencesHashChainFollowChosenPath(
|
|||||||
i, xsize, argb, maxlen, &offset, &len);
|
i, xsize, argb, maxlen, &offset, &len);
|
||||||
assert(len == maxlen);
|
assert(len == maxlen);
|
||||||
refs->refs[size] = PixOrCopyCreateCopy(offset, len);
|
refs->refs[size] = PixOrCopyCreateCopy(offset, len);
|
||||||
|
if (use_color_cache) {
|
||||||
for (k = 0; k < len; ++k) {
|
for (k = 0; k < len; ++k) {
|
||||||
VP8LColorCacheInsert(&hashers, argb[i + k]);
|
VP8LColorCacheInsert(&hashers, argb[i + k]);
|
||||||
if (i + k + 1 < pix_count) {
|
}
|
||||||
// Add to the hash_chain (but cannot add the last pixel).
|
}
|
||||||
|
{
|
||||||
|
const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i;
|
||||||
|
for (k = 0; k < last; ++k) {
|
||||||
HashChainInsert(hash_chain, &argb[i + k], i + k);
|
HashChainInsert(hash_chain, &argb[i + k], i + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,7 +631,7 @@ static int BackwardReferencesHashChainFollowChosenPath(
|
|||||||
} else {
|
} else {
|
||||||
refs->refs[size] = PixOrCopyCreateLiteral(argb[i]);
|
refs->refs[size] = PixOrCopyCreateLiteral(argb[i]);
|
||||||
}
|
}
|
||||||
VP8LColorCacheInsert(&hashers, argb[i]);
|
if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
||||||
if (i + 1 < pix_count) {
|
if (i + 1 < pix_count) {
|
||||||
HashChainInsert(hash_chain, &argb[i], i);
|
HashChainInsert(hash_chain, &argb[i], i);
|
||||||
}
|
}
|
||||||
@ -755,13 +780,18 @@ static int ComputeCacheHistogram(const uint32_t* const argb,
|
|||||||
int i;
|
int i;
|
||||||
uint32_t k;
|
uint32_t k;
|
||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
|
const int use_color_cache = (cache_bits > 0);
|
||||||
|
int cc_init = 0;
|
||||||
|
|
||||||
if (!VP8LColorCacheInit(&hashers, cache_bits)) return 0;
|
if (use_color_cache) {
|
||||||
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
|
if (!cc_init) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < refs->size; ++i) {
|
for (i = 0; i < refs->size; ++i) {
|
||||||
const PixOrCopy* const v = &refs->refs[i];
|
const PixOrCopy* const v = &refs->refs[i];
|
||||||
if (PixOrCopyIsLiteral(v)) {
|
if (PixOrCopyIsLiteral(v)) {
|
||||||
if (cache_bits != 0 &&
|
if (use_color_cache &&
|
||||||
VP8LColorCacheContains(&hashers, argb[pixel_index])) {
|
VP8LColorCacheContains(&hashers, argb[pixel_index])) {
|
||||||
// push pixel as a cache index
|
// push pixel as a cache index
|
||||||
const int ix = VP8LColorCacheGetIndex(&hashers, argb[pixel_index]);
|
const int ix = VP8LColorCacheGetIndex(&hashers, argb[pixel_index]);
|
||||||
@ -773,15 +803,17 @@ static int ComputeCacheHistogram(const uint32_t* const argb,
|
|||||||
} else {
|
} else {
|
||||||
VP8LHistogramAddSinglePixOrCopy(histo, v);
|
VP8LHistogramAddSinglePixOrCopy(histo, v);
|
||||||
}
|
}
|
||||||
|
if (use_color_cache) {
|
||||||
for (k = 0; k < PixOrCopyLength(v); ++k) {
|
for (k = 0; k < PixOrCopyLength(v); ++k) {
|
||||||
VP8LColorCacheInsert(&hashers, argb[pixel_index]);
|
VP8LColorCacheInsert(&hashers, argb[pixel_index + k]);
|
||||||
++pixel_index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pixel_index += PixOrCopyLength(v);
|
||||||
|
}
|
||||||
assert(pixel_index == xsize * ysize);
|
assert(pixel_index == xsize * ysize);
|
||||||
(void)xsize; // xsize is not used in non-debug compilations otherwise.
|
(void)xsize; // xsize is not used in non-debug compilations otherwise.
|
||||||
(void)ysize; // ysize is not used in non-debug compilations otherwise.
|
(void)ysize; // ysize is not used in non-debug compilations otherwise.
|
||||||
VP8LColorCacheClear(&hashers);
|
if (cc_init) VP8LColorCacheClear(&hashers);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,11 +21,9 @@ extern "C" {
|
|||||||
// VP8LColorCache.
|
// VP8LColorCache.
|
||||||
|
|
||||||
int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
|
int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
|
||||||
int hash_size;
|
const int hash_size = 1 << hash_bits;
|
||||||
assert(cc != NULL);
|
assert(cc != NULL);
|
||||||
|
assert(hash_bits > 0);
|
||||||
if (hash_bits == 0) hash_bits = 1;
|
|
||||||
hash_size = 1 << hash_bits;
|
|
||||||
cc->colors_ = (uint32_t*)calloc(hash_size, sizeof(*cc->colors_));
|
cc->colors_ = (uint32_t*)calloc(hash_size, sizeof(*cc->colors_));
|
||||||
if (cc->colors_ == NULL) return 0;
|
if (cc->colors_ == NULL) return 0;
|
||||||
cc->hash_shift_ = 32 - hash_bits;
|
cc->hash_shift_ = 32 - hash_bits;
|
||||||
|
Loading…
Reference in New Issue
Block a user