mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 22:28:22 +01:00
Merge "make error-code reporting consistent upon malloc failure"
This commit is contained in:
commit
790207679d
@ -933,7 +933,8 @@ static double ComputeCacheEntropy(const uint32_t* const argb,
|
|||||||
return entropy;
|
return entropy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns how many bits are to be used for a color cache.
|
// *best_cache_bits will contain how many bits are to be used for a color cache.
|
||||||
|
// Returns 0 in case of memory error.
|
||||||
int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
|
int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
|
||||||
int xsize, int ysize, int quality,
|
int xsize, int ysize, int quality,
|
||||||
VP8LHashChain* const hash_chain,
|
VP8LHashChain* const hash_chain,
|
||||||
|
@ -398,7 +398,7 @@ static void RecordResiduals(VP8EncIterator* const it,
|
|||||||
|
|
||||||
#if !defined(DISABLE_TOKEN_BUFFER)
|
#if !defined(DISABLE_TOKEN_BUFFER)
|
||||||
|
|
||||||
static void RecordTokens(VP8EncIterator* const it, const VP8ModeScore* const rd,
|
static int RecordTokens(VP8EncIterator* const it, const VP8ModeScore* const rd,
|
||||||
VP8TBuffer* const tokens) {
|
VP8TBuffer* const tokens) {
|
||||||
int x, y, ch;
|
int x, y, ch;
|
||||||
VP8Residual res;
|
VP8Residual res;
|
||||||
@ -445,6 +445,7 @@ static void RecordTokens(VP8EncIterator* const it, const VP8ModeScore* const rd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
VP8IteratorBytesToNz(it);
|
VP8IteratorBytesToNz(it);
|
||||||
|
return !tokens->error_;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !DISABLE_TOKEN_BUFFER
|
#endif // !DISABLE_TOKEN_BUFFER
|
||||||
@ -651,7 +652,10 @@ static int PreLoopInitialize(VP8Encoder* const enc) {
|
|||||||
for (p = 0; ok && p < enc->num_parts_; ++p) {
|
for (p = 0; ok && p < enc->num_parts_; ++p) {
|
||||||
ok = VP8BitWriterInit(enc->parts_ + p, bytes_per_parts);
|
ok = VP8BitWriterInit(enc->parts_ + p, bytes_per_parts);
|
||||||
}
|
}
|
||||||
if (!ok) VP8EncFreeBitWriters(enc); // malloc error occurred
|
if (!ok) {
|
||||||
|
VP8EncFreeBitWriters(enc); // malloc error occurred
|
||||||
|
WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,7 +784,11 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
|
|||||||
cnt = max_count;
|
cnt = max_count;
|
||||||
}
|
}
|
||||||
VP8Decimate(&it, &info, rd_opt);
|
VP8Decimate(&it, &info, rd_opt);
|
||||||
RecordTokens(&it, &info, &enc->tokens_);
|
ok = RecordTokens(&it, &info, &enc->tokens_);
|
||||||
|
if (!ok) {
|
||||||
|
WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
size_p0 += info.H;
|
size_p0 += info.H;
|
||||||
distortion += info.D;
|
distortion += info.D;
|
||||||
if (is_last_pass) {
|
if (is_last_pass) {
|
||||||
|
@ -263,13 +263,15 @@ static int EmitPartitionsSize(const VP8Encoder* const enc,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static size_t GeneratePartition0(VP8Encoder* const enc) {
|
static int GeneratePartition0(VP8Encoder* const enc) {
|
||||||
VP8BitWriter* const bw = &enc->bw_;
|
VP8BitWriter* const bw = &enc->bw_;
|
||||||
const int mb_size = enc->mb_w_ * enc->mb_h_;
|
const int mb_size = enc->mb_w_ * enc->mb_h_;
|
||||||
uint64_t pos1, pos2, pos3;
|
uint64_t pos1, pos2, pos3;
|
||||||
|
|
||||||
pos1 = VP8BitWriterPos(bw);
|
pos1 = VP8BitWriterPos(bw);
|
||||||
VP8BitWriterInit(bw, mb_size * 7 / 8); // ~7 bits per macroblock
|
if (!VP8BitWriterInit(bw, mb_size * 7 / 8)) { // ~7 bits per macroblock
|
||||||
|
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
VP8PutBitUniform(bw, 0); // colorspace
|
VP8PutBitUniform(bw, 0); // colorspace
|
||||||
VP8PutBitUniform(bw, 0); // clamp type
|
VP8PutBitUniform(bw, 0); // clamp type
|
||||||
|
|
||||||
@ -292,7 +294,10 @@ static size_t GeneratePartition0(VP8Encoder* const enc) {
|
|||||||
enc->pic_->stats->header_bytes[1] = (int)((pos3 - pos2 + 7) >> 3);
|
enc->pic_->stats->header_bytes[1] = (int)((pos3 - pos2 + 7) >> 3);
|
||||||
enc->pic_->stats->alpha_data_size = (int)enc->alpha_data_size_;
|
enc->pic_->stats->alpha_data_size = (int)enc->alpha_data_size_;
|
||||||
}
|
}
|
||||||
return !bw->error_;
|
if (bw->error_) {
|
||||||
|
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8EncFreeBitWriters(VP8Encoder* const enc) {
|
void VP8EncFreeBitWriters(VP8Encoder* const enc) {
|
||||||
@ -314,7 +319,8 @@ int VP8EncWrite(VP8Encoder* const enc) {
|
|||||||
int p;
|
int p;
|
||||||
|
|
||||||
// Partition #0 with header and partition sizes
|
// Partition #0 with header and partition sizes
|
||||||
ok = !!GeneratePartition0(enc);
|
ok = GeneratePartition0(enc);
|
||||||
|
if (!ok) return 0;
|
||||||
|
|
||||||
// Compute VP8 size
|
// Compute VP8 size
|
||||||
vp8_size = VP8_FRAME_HEADER_SIZE +
|
vp8_size = VP8_FRAME_HEADER_SIZE +
|
||||||
|
@ -225,7 +225,7 @@ int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
|
|||||||
const uint8_t* const probas, int final_pass) {
|
const uint8_t* const probas, int final_pass) {
|
||||||
const VP8Tokens* p = b->pages_;
|
const VP8Tokens* p = b->pages_;
|
||||||
(void)final_pass;
|
(void)final_pass;
|
||||||
if (b->error_) return 0;
|
assert(!b->error_);
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
const VP8Tokens* const next = p->next_;
|
const VP8Tokens* const next = p->next_;
|
||||||
const int N = (next == NULL) ? b->left_ : 0;
|
const int N = (next == NULL) ? b->left_ : 0;
|
||||||
@ -251,7 +251,7 @@ int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
|
|||||||
size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas) {
|
size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas) {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
const VP8Tokens* p = b->pages_;
|
const VP8Tokens* p = b->pages_;
|
||||||
if (b->error_) return 0;
|
assert(!b->error_);
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
const VP8Tokens* const next = p->next_;
|
const VP8Tokens* const next = p->next_;
|
||||||
const int N = (next == NULL) ? b->left_ : 0;
|
const int N = (next == NULL) ? b->left_ : 0;
|
||||||
|
108
src/enc/vp8l.c
108
src/enc/vp8l.c
@ -181,6 +181,7 @@ static int AnalyzeAndInit(VP8LEncoder* const enc, WebPImageHint image_hint) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns false in case of memory error.
|
||||||
static int GetHuffBitLengthsAndCodes(
|
static int GetHuffBitLengthsAndCodes(
|
||||||
const VP8LHistogramSet* const histogram_image,
|
const VP8LHistogramSet* const histogram_image,
|
||||||
HuffmanTreeCode* const huffman_codes) {
|
HuffmanTreeCode* const huffman_codes) {
|
||||||
@ -426,7 +427,7 @@ static void WriteHuffmanCode(VP8LBitWriter* const bw,
|
|||||||
VP8LWriteBits(bw, depth, symbol);
|
VP8LWriteBits(bw, depth, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StoreImageToBitMask(
|
static WebPEncodingError StoreImageToBitMask(
|
||||||
VP8LBitWriter* const bw, int width, int histo_bits,
|
VP8LBitWriter* const bw, int width, int histo_bits,
|
||||||
VP8LBackwardRefs* const refs,
|
VP8LBackwardRefs* const refs,
|
||||||
const uint16_t* histogram_symbols,
|
const uint16_t* histogram_symbols,
|
||||||
@ -473,17 +474,19 @@ static void StoreImageToBitMask(
|
|||||||
}
|
}
|
||||||
VP8LRefsCursorNext(&c);
|
VP8LRefsCursorNext(&c);
|
||||||
}
|
}
|
||||||
|
return bw->error_ ? VP8_ENC_ERROR_OUT_OF_MEMORY : VP8_ENC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
|
// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
|
||||||
static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
||||||
const uint32_t* const argb,
|
const uint32_t* const argb,
|
||||||
VP8LHashChain* const hash_chain,
|
VP8LHashChain* const hash_chain,
|
||||||
VP8LBackwardRefs refs_array[2],
|
VP8LBackwardRefs refs_array[2],
|
||||||
int width, int height, int quality) {
|
int width, int height,
|
||||||
|
int quality) {
|
||||||
int i;
|
int i;
|
||||||
int ok = 0;
|
|
||||||
int max_tokens = 0;
|
int max_tokens = 0;
|
||||||
|
WebPEncodingError err = VP8_ENC_OK;
|
||||||
VP8LBackwardRefs* refs;
|
VP8LBackwardRefs* refs;
|
||||||
HuffmanTreeToken* tokens = NULL;
|
HuffmanTreeToken* tokens = NULL;
|
||||||
HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
|
HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
|
||||||
@ -491,12 +494,16 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
VP8LHistogramSet* const histogram_image = VP8LAllocateHistogramSet(1, 0);
|
VP8LHistogramSet* const histogram_image = VP8LAllocateHistogramSet(1, 0);
|
||||||
HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
|
HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
|
||||||
3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
|
3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
|
||||||
if (histogram_image == NULL || huff_tree == NULL) goto Error;
|
if (histogram_image == NULL || huff_tree == NULL) {
|
||||||
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate backward references from ARGB image.
|
// Calculate backward references from ARGB image.
|
||||||
refs = VP8LGetBackwardReferences(width, height, argb, quality, 0, 1,
|
refs = VP8LGetBackwardReferences(width, height, argb, quality, 0, 1,
|
||||||
hash_chain, refs_array);
|
hash_chain, refs_array);
|
||||||
if (refs == NULL) {
|
if (refs == NULL) {
|
||||||
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
// Build histogram image and symbols from backward references.
|
// Build histogram image and symbols from backward references.
|
||||||
@ -505,6 +512,7 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
// Create Huffman bit lengths and codes for each histogram image.
|
// Create Huffman bit lengths and codes for each histogram image.
|
||||||
assert(histogram_image->size == 1);
|
assert(histogram_image->size == 1);
|
||||||
if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
|
if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
|
||||||
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +528,10 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
|
tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
|
||||||
if (tokens == NULL) goto Error;
|
if (tokens == NULL) {
|
||||||
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
// Store Huffman codes.
|
// Store Huffman codes.
|
||||||
for (i = 0; i < 5; ++i) {
|
for (i = 0; i < 5; ++i) {
|
||||||
@ -530,24 +541,25 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store actual literals.
|
// Store actual literals.
|
||||||
StoreImageToBitMask(bw, width, 0, refs, histogram_symbols, huffman_codes);
|
err = StoreImageToBitMask(bw, width, 0, refs, histogram_symbols,
|
||||||
ok = 1;
|
huffman_codes);
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
WebPSafeFree(tokens);
|
WebPSafeFree(tokens);
|
||||||
WebPSafeFree(huff_tree);
|
WebPSafeFree(huff_tree);
|
||||||
VP8LFreeHistogramSet(histogram_image);
|
VP8LFreeHistogramSet(histogram_image);
|
||||||
WebPSafeFree(huffman_codes[0].codes);
|
WebPSafeFree(huffman_codes[0].codes);
|
||||||
return ok;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int EncodeImageInternal(VP8LBitWriter* const bw,
|
static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
|
||||||
const uint32_t* const argb,
|
const uint32_t* const argb,
|
||||||
VP8LHashChain* const hash_chain,
|
VP8LHashChain* const hash_chain,
|
||||||
VP8LBackwardRefs refs_array[2],
|
VP8LBackwardRefs refs_array[2],
|
||||||
int width, int height, int quality,
|
int width, int height, int quality,
|
||||||
int cache_bits, int histogram_bits) {
|
int cache_bits,
|
||||||
int ok = 0;
|
int histogram_bits) {
|
||||||
|
WebPEncodingError err = VP8_ENC_OK;
|
||||||
const int use_2d_locality = 1;
|
const int use_2d_locality = 1;
|
||||||
const int use_color_cache = (cache_bits > 0);
|
const int use_color_cache = (cache_bits > 0);
|
||||||
const uint32_t histogram_image_xysize =
|
const uint32_t histogram_image_xysize =
|
||||||
@ -631,12 +643,12 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
histogram_image_size = max_index;
|
histogram_image_size = max_index;
|
||||||
|
|
||||||
VP8LWriteBits(bw, 3, histogram_bits - 2);
|
VP8LWriteBits(bw, 3, histogram_bits - 2);
|
||||||
ok = EncodeImageNoHuffman(bw, histogram_argb, hash_chain, refs_array,
|
err = EncodeImageNoHuffman(bw, histogram_argb, hash_chain, refs_array,
|
||||||
VP8LSubSampleSize(width, histogram_bits),
|
VP8LSubSampleSize(width, histogram_bits),
|
||||||
VP8LSubSampleSize(height, histogram_bits),
|
VP8LSubSampleSize(height, histogram_bits),
|
||||||
quality);
|
quality);
|
||||||
WebPSafeFree(histogram_argb);
|
WebPSafeFree(histogram_argb);
|
||||||
if (!ok) goto Error;
|
if (err != VP8_ENC_OK) goto Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,9 +677,8 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store actual literals.
|
// Store actual literals.
|
||||||
StoreImageToBitMask(bw, width, histogram_bits, &refs,
|
err = StoreImageToBitMask(bw, width, histogram_bits, &refs,
|
||||||
histogram_symbols, huffman_codes);
|
histogram_symbols, huffman_codes);
|
||||||
ok = 1;
|
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
WebPSafeFree(tokens);
|
WebPSafeFree(tokens);
|
||||||
@ -679,7 +690,7 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
WebPSafeFree(huffman_codes);
|
WebPSafeFree(huffman_codes);
|
||||||
}
|
}
|
||||||
WebPSafeFree(histogram_symbols);
|
WebPSafeFree(histogram_symbols);
|
||||||
return ok;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -687,7 +698,7 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
|
|
||||||
// Check if it would be a good idea to subtract green from red and blue. We
|
// Check if it would be a good idea to subtract green from red and blue. We
|
||||||
// only impact entropy in red/blue components, don't bother to look at others.
|
// only impact entropy in red/blue components, don't bother to look at others.
|
||||||
static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
static WebPEncodingError EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
VP8LBitWriter* const bw) {
|
VP8LBitWriter* const bw) {
|
||||||
if (!enc->use_palette_) {
|
if (!enc->use_palette_) {
|
||||||
@ -696,7 +707,7 @@ static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
|||||||
double bit_cost_before, bit_cost_after;
|
double bit_cost_before, bit_cost_after;
|
||||||
// Allocate histogram with cache_bits = 1.
|
// Allocate histogram with cache_bits = 1.
|
||||||
VP8LHistogram* const histo = VP8LAllocateHistogram(1);
|
VP8LHistogram* const histo = VP8LAllocateHistogram(1);
|
||||||
if (histo == NULL) return 0;
|
if (histo == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
for (i = 0; i < width * height; ++i) {
|
for (i = 0; i < width * height; ++i) {
|
||||||
const uint32_t c = argb[i];
|
const uint32_t c = argb[i];
|
||||||
++histo->red_[(c >> 16) & 0xff];
|
++histo->red_[(c >> 16) & 0xff];
|
||||||
@ -722,10 +733,10 @@ static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
|||||||
VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
|
VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return VP8_ENC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ApplyPredictFilter(const VP8LEncoder* const enc,
|
static WebPEncodingError ApplyPredictFilter(const VP8LEncoder* const enc,
|
||||||
int width, int height, int quality,
|
int width, int height, int quality,
|
||||||
VP8LBitWriter* const bw) {
|
VP8LBitWriter* const bw) {
|
||||||
const int pred_bits = enc->transform_bits_;
|
const int pred_bits = enc->transform_bits_;
|
||||||
@ -738,18 +749,16 @@ static int ApplyPredictFilter(const VP8LEncoder* const enc,
|
|||||||
VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM);
|
VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM);
|
||||||
assert(pred_bits >= 2);
|
assert(pred_bits >= 2);
|
||||||
VP8LWriteBits(bw, 3, pred_bits - 2);
|
VP8LWriteBits(bw, 3, pred_bits - 2);
|
||||||
if (!EncodeImageNoHuffman(bw, enc->transform_data_,
|
return EncodeImageNoHuffman(bw, enc->transform_data_,
|
||||||
(VP8LHashChain*)&enc->hash_chain_,
|
(VP8LHashChain*)&enc->hash_chain_,
|
||||||
(VP8LBackwardRefs*)enc->refs_, // cast const away
|
(VP8LBackwardRefs*)enc->refs_, // cast const away
|
||||||
transform_width, transform_height,
|
transform_width, transform_height,
|
||||||
quality)) {
|
quality);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ApplyCrossColorFilter(const VP8LEncoder* const enc,
|
static WebPEncodingError ApplyCrossColorFilter(const VP8LEncoder* const enc,
|
||||||
int width, int height, int quality,
|
int width, int height,
|
||||||
|
int quality,
|
||||||
VP8LBitWriter* const bw) {
|
VP8LBitWriter* const bw) {
|
||||||
const int ccolor_transform_bits = enc->transform_bits_;
|
const int ccolor_transform_bits = enc->transform_bits_;
|
||||||
const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
|
const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
|
||||||
@ -761,14 +770,11 @@ static int ApplyCrossColorFilter(const VP8LEncoder* const enc,
|
|||||||
VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM);
|
VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM);
|
||||||
assert(ccolor_transform_bits >= 2);
|
assert(ccolor_transform_bits >= 2);
|
||||||
VP8LWriteBits(bw, 3, ccolor_transform_bits - 2);
|
VP8LWriteBits(bw, 3, ccolor_transform_bits - 2);
|
||||||
if (!EncodeImageNoHuffman(bw, enc->transform_data_,
|
return EncodeImageNoHuffman(bw, enc->transform_data_,
|
||||||
(VP8LHashChain*)&enc->hash_chain_,
|
(VP8LHashChain*)&enc->hash_chain_,
|
||||||
(VP8LBackwardRefs*)enc->refs_, // cast const away
|
(VP8LBackwardRefs*)enc->refs_, // cast const away
|
||||||
transform_width, transform_height,
|
transform_width, transform_height,
|
||||||
quality)) {
|
quality);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -963,11 +969,8 @@ static WebPEncodingError EncodePalette(VP8LBitWriter* const bw,
|
|||||||
for (i = palette_size - 1; i >= 1; --i) {
|
for (i = palette_size - 1; i >= 1; --i) {
|
||||||
palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
|
palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
|
||||||
}
|
}
|
||||||
if (!EncodeImageNoHuffman(bw, palette, &enc->hash_chain_, enc->refs_,
|
err = EncodeImageNoHuffman(bw, palette, &enc->hash_chain_, enc->refs_,
|
||||||
palette_size, 1, quality)) {
|
palette_size, 1, quality);
|
||||||
err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
|
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
WebPSafeFree(row);
|
WebPSafeFree(row);
|
||||||
@ -1089,23 +1092,17 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Apply transforms and write transform data.
|
// Apply transforms and write transform data.
|
||||||
|
|
||||||
if (!EvalAndApplySubtractGreen(enc, enc->current_width_, height, bw)) {
|
err = EvalAndApplySubtractGreen(enc, enc->current_width_, height, bw);
|
||||||
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
if (err != VP8_ENC_OK) goto Error;
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enc->use_predict_) {
|
if (enc->use_predict_) {
|
||||||
if (!ApplyPredictFilter(enc, enc->current_width_, height, quality, bw)) {
|
err = ApplyPredictFilter(enc, enc->current_width_, height, quality, bw);
|
||||||
err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
|
if (err != VP8_ENC_OK) goto Error;
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enc->use_cross_color_) {
|
if (enc->use_cross_color_) {
|
||||||
if (!ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw)) {
|
err = ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw);
|
||||||
err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
|
if (err != VP8_ENC_OK) goto Error;
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT); // No more transforms.
|
VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT); // No more transforms.
|
||||||
@ -1117,7 +1114,7 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
|
|||||||
if (!VP8LCalculateEstimateForCacheSize(enc->argb_, enc->current_width_,
|
if (!VP8LCalculateEstimateForCacheSize(enc->argb_, enc->current_width_,
|
||||||
height, quality, &enc->hash_chain_,
|
height, quality, &enc->hash_chain_,
|
||||||
&enc->refs_[0], &enc->cache_bits_)) {
|
&enc->refs_[0], &enc->cache_bits_)) {
|
||||||
err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1125,12 +1122,10 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Encode and write the transformed image.
|
// Encode and write the transformed image.
|
||||||
|
|
||||||
if (!EncodeImageInternal(bw, enc->argb_, &enc->hash_chain_, enc->refs_,
|
err = EncodeImageInternal(bw, enc->argb_, &enc->hash_chain_, enc->refs_,
|
||||||
enc->current_width_, height, quality,
|
enc->current_width_, height, quality,
|
||||||
enc->cache_bits_, enc->histo_bits_)) {
|
enc->cache_bits_, enc->histo_bits_);
|
||||||
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
if (err != VP8_ENC_OK) goto Error;
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (picture->stats != NULL) {
|
if (picture->stats != NULL) {
|
||||||
WebPAuxStats* const stats = picture->stats;
|
WebPAuxStats* const stats = picture->stats;
|
||||||
@ -1247,4 +1242,3 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user