Reduce memory footprint for encoding WebP lossless.

Reduce calls to Malloc (WebPSafeMalloc/WebPSafeCalloc) for:
- Building HashChain data-structure used in creating the backward references.
- Creating Backward references for LZ77 or RLE coding.
- Creating Huffman tree for encoding the image.
For the above mentioned code-paths, allocate memory once and re-use it
subsequently.

Reduce the foorprint of VP8LHistogram struct by changing the Struct
field 'literal_' from an array of constant size to dynamically allocated
buffer based on the input parameter cache_bits.

Initialize BitWriter buffer corresponding to 16bpp (2*W*H).
There are some hard-files that are compressed at 12 bpp or more. The
realloc is costly and can be avoided for most of the WebP lossless
images by allocating some extra memory at the encoder initializaiton.

Change-Id: I1ea8cf60df727b8eb41547901f376c9a585e6095
This commit is contained in:
Vikas Arora
2014-04-25 16:01:49 -07:00
committed by Pascal Massimino
parent 1d62acf6af
commit 0b896101b4
8 changed files with 472 additions and 328 deletions

View File

@ -115,34 +115,59 @@ static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) {
// -----------------------------------------------------------------------------
// VP8LBackwardRefs
typedef struct {
#define HASH_BITS 18
#define HASH_SIZE (1 << HASH_BITS)
typedef struct VP8LHashChain VP8LHashChain;
struct VP8LHashChain {
// Stores the most recently added position with the given hash value.
int32_t hash_to_first_index_[HASH_SIZE];
// chain_[pos] stores the previous position with the same hash value
// for every pixel in the image.
int32_t* chain_;
// This is the maximum size of the hash_chain that can be constructed.
// Typically this is the pixel count (width x height) for a given image.
int size_;
};
VP8LHashChain* VP8LHashChainNew(int size);
void VP8LHashChainDelete(VP8LHashChain* const p);
typedef struct VP8LBackwardRefs VP8LBackwardRefs;
struct VP8LBackwardRefs {
PixOrCopy* refs;
int size; // currently used
int max_size; // maximum capacity
} VP8LBackwardRefs;
};
// Initialize the object. Must be called first. 'refs' can be NULL.
void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs);
// Release backward references. 'refs' can be NULL.
void VP8LBackwardRefsDelete(VP8LBackwardRefs* const refs);
// Release memory and re-initialize the object. 'refs' can be NULL.
void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs);
// Allocate 'max_size' references. Returns NULL in case of memory error.
VP8LBackwardRefs* VP8LBackwardRefsNew(int max_size);
// Allocate 'max_size' references. Returns false in case of memory error.
int VP8LBackwardRefsAlloc(VP8LBackwardRefs* const refs, int max_size);
// Copies the 'src' backward refs to the 'dst'. Returns 0 if there's mismatch
// in the capacity (max_size) of 'src' and 'dst' refs.
int VP8LBackwardRefsCopy(const VP8LBackwardRefs* const src,
VP8LBackwardRefs* const dst);
// -----------------------------------------------------------------------------
// Main entry points
// Evaluates best possible backward references for specified quality.
// Further optimize for 2D locality if use_2d_locality flag is set.
int VP8LGetBackwardReferences(int width, int height,
const uint32_t* const argb,
int quality, int cache_bits, int use_2d_locality,
VP8LBackwardRefs* const best);
// The return value is the pointer to the best of the two backward refs viz,
// refs[0] or refs[1].
VP8LBackwardRefs* VP8LGetBackwardReferences(
int width, int height, const uint32_t* const argb, int quality,
int cache_bits, int use_2d_locality, VP8LHashChain* const hash_chain,
VP8LBackwardRefs* const refs[2]);
// Produce an estimate for a good color cache size for the image.
int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
int xsize, int ysize, int quality,
VP8LHashChain* const hash_chain,
VP8LBackwardRefs* const ref,
int* const best_cache_bits);
#ifdef __cplusplus