mirror of
https://github.com/webmproject/libwebp.git
synced 2025-02-13 15:32:53 +01:00
Unify the API between VP8BitWriter and VP8LBitWriter
BitReader will be next... Change-Id: Icd9e7ab2e3890131e664c0523627d9b8c5399a74
This commit is contained in:
parent
f7ada560ce
commit
5b90d8fe42
@ -77,7 +77,7 @@ static int EncodeLossless(const uint8_t* const data, int width, int height,
|
|||||||
WebPPictureFree(&picture);
|
WebPPictureFree(&picture);
|
||||||
ok = ok && !bw->error_;
|
ok = ok && !bw->error_;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
VP8LBitWriterDestroy(bw);
|
VP8LBitWriterWipeOut(bw);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -133,10 +133,10 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
|
|||||||
if (output_size > data_size) {
|
if (output_size > data_size) {
|
||||||
// compressed size is larger than source! Revert to uncompressed mode.
|
// compressed size is larger than source! Revert to uncompressed mode.
|
||||||
method = ALPHA_NO_COMPRESSION;
|
method = ALPHA_NO_COMPRESSION;
|
||||||
VP8LBitWriterDestroy(&tmp_bw);
|
VP8LBitWriterWipeOut(&tmp_bw);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
VP8LBitWriterDestroy(&tmp_bw);
|
VP8LBitWriterWipeOut(&tmp_bw);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
|
|||||||
ok = ok && VP8BitWriterAppend(&result->bw, output, output_size);
|
ok = ok && VP8BitWriterAppend(&result->bw, output, output_size);
|
||||||
|
|
||||||
if (method != ALPHA_NO_COMPRESSION) {
|
if (method != ALPHA_NO_COMPRESSION) {
|
||||||
VP8LBitWriterDestroy(&tmp_bw);
|
VP8LBitWriterWipeOut(&tmp_bw);
|
||||||
}
|
}
|
||||||
ok = ok && !result->bw.error_;
|
ok = ok && !result->bw.error_;
|
||||||
result->score = VP8BitWriterSize(&result->bw);
|
result->score = VP8BitWriterSize(&result->bw);
|
||||||
|
@ -197,16 +197,16 @@ static void PutSegmentHeader(VP8BitWriter* const bw,
|
|||||||
// we always use absolute values, not relative ones
|
// we always use absolute values, not relative ones
|
||||||
VP8PutBitUniform(bw, 1); // (segment_feature_mode = 1. Paragraph 9.3.)
|
VP8PutBitUniform(bw, 1); // (segment_feature_mode = 1. Paragraph 9.3.)
|
||||||
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
||||||
VP8PutSignedValue(bw, enc->dqm_[s].quant_, 7);
|
VP8PutSignedBits(bw, enc->dqm_[s].quant_, 7);
|
||||||
}
|
}
|
||||||
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
||||||
VP8PutSignedValue(bw, enc->dqm_[s].fstrength_, 6);
|
VP8PutSignedBits(bw, enc->dqm_[s].fstrength_, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hdr->update_map_) {
|
if (hdr->update_map_) {
|
||||||
for (s = 0; s < 3; ++s) {
|
for (s = 0; s < 3; ++s) {
|
||||||
if (VP8PutBitUniform(bw, (proba->segments_[s] != 255u))) {
|
if (VP8PutBitUniform(bw, (proba->segments_[s] != 255u))) {
|
||||||
VP8PutValue(bw, proba->segments_[s], 8);
|
VP8PutBits(bw, proba->segments_[s], 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,17 +218,17 @@ static void PutFilterHeader(VP8BitWriter* const bw,
|
|||||||
const VP8FilterHeader* const hdr) {
|
const VP8FilterHeader* const hdr) {
|
||||||
const int use_lf_delta = (hdr->i4x4_lf_delta_ != 0);
|
const int use_lf_delta = (hdr->i4x4_lf_delta_ != 0);
|
||||||
VP8PutBitUniform(bw, hdr->simple_);
|
VP8PutBitUniform(bw, hdr->simple_);
|
||||||
VP8PutValue(bw, hdr->level_, 6);
|
VP8PutBits(bw, hdr->level_, 6);
|
||||||
VP8PutValue(bw, hdr->sharpness_, 3);
|
VP8PutBits(bw, hdr->sharpness_, 3);
|
||||||
if (VP8PutBitUniform(bw, use_lf_delta)) {
|
if (VP8PutBitUniform(bw, use_lf_delta)) {
|
||||||
// '0' is the default value for i4x4_lf_delta_ at frame #0.
|
// '0' is the default value for i4x4_lf_delta_ at frame #0.
|
||||||
const int need_update = (hdr->i4x4_lf_delta_ != 0);
|
const int need_update = (hdr->i4x4_lf_delta_ != 0);
|
||||||
if (VP8PutBitUniform(bw, need_update)) {
|
if (VP8PutBitUniform(bw, need_update)) {
|
||||||
// we don't use ref_lf_delta => emit four 0 bits
|
// we don't use ref_lf_delta => emit four 0 bits
|
||||||
VP8PutValue(bw, 0, 4);
|
VP8PutBits(bw, 0, 4);
|
||||||
// we use mode_lf_delta for i4x4
|
// we use mode_lf_delta for i4x4
|
||||||
VP8PutSignedValue(bw, hdr->i4x4_lf_delta_, 6);
|
VP8PutSignedBits(bw, hdr->i4x4_lf_delta_, 6);
|
||||||
VP8PutValue(bw, 0, 3); // all others unused
|
VP8PutBits(bw, 0, 3); // all others unused
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,12 +236,12 @@ static void PutFilterHeader(VP8BitWriter* const bw,
|
|||||||
// Nominal quantization parameters
|
// Nominal quantization parameters
|
||||||
static void PutQuant(VP8BitWriter* const bw,
|
static void PutQuant(VP8BitWriter* const bw,
|
||||||
const VP8Encoder* const enc) {
|
const VP8Encoder* const enc) {
|
||||||
VP8PutValue(bw, enc->base_quant_, 7);
|
VP8PutBits(bw, enc->base_quant_, 7);
|
||||||
VP8PutSignedValue(bw, enc->dq_y1_dc_, 4);
|
VP8PutSignedBits(bw, enc->dq_y1_dc_, 4);
|
||||||
VP8PutSignedValue(bw, enc->dq_y2_dc_, 4);
|
VP8PutSignedBits(bw, enc->dq_y2_dc_, 4);
|
||||||
VP8PutSignedValue(bw, enc->dq_y2_ac_, 4);
|
VP8PutSignedBits(bw, enc->dq_y2_ac_, 4);
|
||||||
VP8PutSignedValue(bw, enc->dq_uv_dc_, 4);
|
VP8PutSignedBits(bw, enc->dq_uv_dc_, 4);
|
||||||
VP8PutSignedValue(bw, enc->dq_uv_ac_, 4);
|
VP8PutSignedBits(bw, enc->dq_uv_ac_, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Partition sizes
|
// Partition sizes
|
||||||
@ -277,7 +277,7 @@ static int GeneratePartition0(VP8Encoder* const enc) {
|
|||||||
|
|
||||||
PutSegmentHeader(bw, enc);
|
PutSegmentHeader(bw, enc);
|
||||||
PutFilterHeader(bw, &enc->filter_hdr_);
|
PutFilterHeader(bw, &enc->filter_hdr_);
|
||||||
VP8PutValue(bw, enc->num_parts_ == 8 ? 3 :
|
VP8PutBits(bw, enc->num_parts_ == 8 ? 3 :
|
||||||
enc->num_parts_ == 4 ? 2 :
|
enc->num_parts_ == 4 ? 2 :
|
||||||
enc->num_parts_ == 2 ? 1 : 0, 2);
|
enc->num_parts_ == 2 ? 1 : 0, 2);
|
||||||
PutQuant(bw, enc);
|
PutQuant(bw, enc);
|
||||||
|
@ -491,14 +491,14 @@ void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas) {
|
|||||||
const uint8_t p0 = probas->coeffs_[t][b][c][p];
|
const uint8_t p0 = probas->coeffs_[t][b][c][p];
|
||||||
const int update = (p0 != VP8CoeffsProba0[t][b][c][p]);
|
const int update = (p0 != VP8CoeffsProba0[t][b][c][p]);
|
||||||
if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) {
|
if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) {
|
||||||
VP8PutValue(bw, p0, 8);
|
VP8PutBits(bw, p0, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (VP8PutBitUniform(bw, probas->use_skip_proba_)) {
|
if (VP8PutBitUniform(bw, probas->use_skip_proba_)) {
|
||||||
VP8PutValue(bw, probas->skip_proba_, 8);
|
VP8PutBits(bw, probas->skip_proba_, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,9 +470,9 @@ static void StoreHuffmanTreeOfHuffmanTreeToBitMask(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VP8LWriteBits(bw, 4, codes_to_store - 4);
|
VP8LPutBits(bw, codes_to_store - 4, 4);
|
||||||
for (i = 0; i < codes_to_store; ++i) {
|
for (i = 0; i < codes_to_store; ++i) {
|
||||||
VP8LWriteBits(bw, 3, code_length_bitdepth[kStorageOrder[i]]);
|
VP8LPutBits(bw, code_length_bitdepth[kStorageOrder[i]], 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,16 +500,16 @@ static void StoreHuffmanTreeToBitMask(
|
|||||||
for (i = 0; i < num_tokens; ++i) {
|
for (i = 0; i < num_tokens; ++i) {
|
||||||
const int ix = tokens[i].code;
|
const int ix = tokens[i].code;
|
||||||
const int extra_bits = tokens[i].extra_bits;
|
const int extra_bits = tokens[i].extra_bits;
|
||||||
VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]);
|
VP8LPutBits(bw, huffman_code->codes[ix], huffman_code->code_lengths[ix]);
|
||||||
switch (ix) {
|
switch (ix) {
|
||||||
case 16:
|
case 16:
|
||||||
VP8LWriteBits(bw, 2, extra_bits);
|
VP8LPutBits(bw, extra_bits, 2);
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 17:
|
||||||
VP8LWriteBits(bw, 3, extra_bits);
|
VP8LPutBits(bw, extra_bits, 3);
|
||||||
break;
|
break;
|
||||||
case 18:
|
case 18:
|
||||||
VP8LWriteBits(bw, 7, extra_bits);
|
VP8LPutBits(bw, extra_bits, 7);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,7 +529,7 @@ static void StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
|||||||
huffman_code.code_lengths = code_length_bitdepth;
|
huffman_code.code_lengths = code_length_bitdepth;
|
||||||
huffman_code.codes = code_length_bitdepth_symbols;
|
huffman_code.codes = code_length_bitdepth_symbols;
|
||||||
|
|
||||||
VP8LWriteBits(bw, 1, 0);
|
VP8LPutBits(bw, 0, 1);
|
||||||
num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
|
num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
|
||||||
{
|
{
|
||||||
uint32_t histogram[CODE_LENGTH_CODES] = { 0 };
|
uint32_t histogram[CODE_LENGTH_CODES] = { 0 };
|
||||||
@ -566,13 +566,13 @@ static void StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
|
write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
|
||||||
length = write_trimmed_length ? trimmed_length : num_tokens;
|
length = write_trimmed_length ? trimmed_length : num_tokens;
|
||||||
VP8LWriteBits(bw, 1, write_trimmed_length);
|
VP8LPutBits(bw, write_trimmed_length, 1);
|
||||||
if (write_trimmed_length) {
|
if (write_trimmed_length) {
|
||||||
const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1);
|
const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1);
|
||||||
const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2;
|
const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2;
|
||||||
VP8LWriteBits(bw, 3, nbitpairs - 1);
|
VP8LPutBits(bw, nbitpairs - 1, 3);
|
||||||
assert(trimmed_length >= 2);
|
assert(trimmed_length >= 2);
|
||||||
VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2);
|
VP8LPutBits(bw, trimmed_length - 2, nbitpairs * 2);
|
||||||
}
|
}
|
||||||
StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
|
StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
|
||||||
}
|
}
|
||||||
@ -599,19 +599,19 @@ static void StoreHuffmanCode(VP8LBitWriter* const bw,
|
|||||||
|
|
||||||
if (count == 0) { // emit minimal tree for empty cases
|
if (count == 0) { // emit minimal tree for empty cases
|
||||||
// bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
|
// bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
|
||||||
VP8LWriteBits(bw, 4, 0x01);
|
VP8LPutBits(bw, 0x01, 4);
|
||||||
} else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
|
} else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
|
||||||
VP8LWriteBits(bw, 1, 1); // Small tree marker to encode 1 or 2 symbols.
|
VP8LPutBits(bw, 1, 1); // Small tree marker to encode 1 or 2 symbols.
|
||||||
VP8LWriteBits(bw, 1, count - 1);
|
VP8LPutBits(bw, count - 1, 1);
|
||||||
if (symbols[0] <= 1) {
|
if (symbols[0] <= 1) {
|
||||||
VP8LWriteBits(bw, 1, 0); // Code bit for small (1 bit) symbol value.
|
VP8LPutBits(bw, 0, 1); // Code bit for small (1 bit) symbol value.
|
||||||
VP8LWriteBits(bw, 1, symbols[0]);
|
VP8LPutBits(bw, symbols[0], 1);
|
||||||
} else {
|
} else {
|
||||||
VP8LWriteBits(bw, 1, 1);
|
VP8LPutBits(bw, 1, 1);
|
||||||
VP8LWriteBits(bw, 8, symbols[0]);
|
VP8LPutBits(bw, symbols[0], 8);
|
||||||
}
|
}
|
||||||
if (count == 2) {
|
if (count == 2) {
|
||||||
VP8LWriteBits(bw, 8, symbols[1]);
|
VP8LPutBits(bw, symbols[1], 8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StoreFullHuffmanCode(bw, huff_tree, tokens, huffman_code);
|
StoreFullHuffmanCode(bw, huff_tree, tokens, huffman_code);
|
||||||
@ -623,7 +623,7 @@ static void WriteHuffmanCode(VP8LBitWriter* const bw,
|
|||||||
int code_index) {
|
int code_index) {
|
||||||
const int depth = code->code_lengths[code_index];
|
const int depth = code->code_lengths[code_index];
|
||||||
const int symbol = code->codes[code_index];
|
const int symbol = code->codes[code_index];
|
||||||
VP8LWriteBits(bw, depth, symbol);
|
VP8LPutBits(bw, symbol, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebPEncodingError StoreImageToBitMask(
|
static WebPEncodingError StoreImageToBitMask(
|
||||||
@ -659,12 +659,12 @@ static WebPEncodingError StoreImageToBitMask(
|
|||||||
|
|
||||||
VP8LPrefixEncode(v->len, &code, &n_bits, &bits);
|
VP8LPrefixEncode(v->len, &code, &n_bits, &bits);
|
||||||
WriteHuffmanCode(bw, codes, 256 + code);
|
WriteHuffmanCode(bw, codes, 256 + code);
|
||||||
VP8LWriteBits(bw, n_bits, bits);
|
VP8LPutBits(bw, bits, n_bits);
|
||||||
|
|
||||||
distance = PixOrCopyDistance(v);
|
distance = PixOrCopyDistance(v);
|
||||||
VP8LPrefixEncode(distance, &code, &n_bits, &bits);
|
VP8LPrefixEncode(distance, &code, &n_bits, &bits);
|
||||||
WriteHuffmanCode(bw, codes + 4, code);
|
WriteHuffmanCode(bw, codes + 4, code);
|
||||||
VP8LWriteBits(bw, n_bits, bits);
|
VP8LPutBits(bw, bits, n_bits);
|
||||||
}
|
}
|
||||||
x += PixOrCopyLength(v);
|
x += PixOrCopyLength(v);
|
||||||
while (x >= width) {
|
while (x >= width) {
|
||||||
@ -716,7 +716,7 @@ static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No color cache, no Huffman image.
|
// No color cache, no Huffman image.
|
||||||
VP8LWriteBits(bw, 1, 0);
|
VP8LPutBits(bw, 0, 1);
|
||||||
|
|
||||||
// Find maximum number of symbols for the huffman tree-set.
|
// Find maximum number of symbols for the huffman tree-set.
|
||||||
for (i = 0; i < 5; ++i) {
|
for (i = 0; i < 5; ++i) {
|
||||||
@ -823,15 +823,15 @@ static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
histogram_image = NULL;
|
histogram_image = NULL;
|
||||||
|
|
||||||
// Color Cache parameters.
|
// Color Cache parameters.
|
||||||
VP8LWriteBits(bw, 1, use_color_cache);
|
VP8LPutBits(bw, use_color_cache, 1);
|
||||||
if (use_color_cache) {
|
if (use_color_cache) {
|
||||||
VP8LWriteBits(bw, 4, cache_bits);
|
VP8LPutBits(bw, cache_bits, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Huffman image + meta huffman.
|
// Huffman image + meta huffman.
|
||||||
{
|
{
|
||||||
const int write_histogram_image = (histogram_image_size > 1);
|
const int write_histogram_image = (histogram_image_size > 1);
|
||||||
VP8LWriteBits(bw, 1, write_histogram_image);
|
VP8LPutBits(bw, write_histogram_image, 1);
|
||||||
if (write_histogram_image) {
|
if (write_histogram_image) {
|
||||||
uint32_t* const histogram_argb =
|
uint32_t* const histogram_argb =
|
||||||
(uint32_t*)WebPSafeMalloc(histogram_image_xysize,
|
(uint32_t*)WebPSafeMalloc(histogram_image_xysize,
|
||||||
@ -851,7 +851,7 @@ static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
histogram_image_size = max_index;
|
histogram_image_size = max_index;
|
||||||
|
|
||||||
VP8LWriteBits(bw, 3, histogram_bits - 2);
|
VP8LPutBits(bw, histogram_bits - 2, 3);
|
||||||
err = 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),
|
||||||
@ -916,8 +916,8 @@ static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
|
|
||||||
static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
|
static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
|
||||||
VP8LBitWriter* const bw) {
|
VP8LBitWriter* const bw) {
|
||||||
VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
|
VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
|
||||||
VP8LWriteBits(bw, 2, SUBTRACT_GREEN);
|
VP8LPutBits(bw, SUBTRACT_GREEN, 2);
|
||||||
VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
|
VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,10 +930,10 @@ static WebPEncodingError ApplyPredictFilter(const VP8LEncoder* const enc,
|
|||||||
|
|
||||||
VP8LResidualImage(width, height, pred_bits, enc->argb_, enc->argb_scratch_,
|
VP8LResidualImage(width, height, pred_bits, enc->argb_, enc->argb_scratch_,
|
||||||
enc->transform_data_);
|
enc->transform_data_);
|
||||||
VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
|
VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
|
||||||
VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM);
|
VP8LPutBits(bw, PREDICTOR_TRANSFORM, 2);
|
||||||
assert(pred_bits >= 2);
|
assert(pred_bits >= 2);
|
||||||
VP8LWriteBits(bw, 3, pred_bits - 2);
|
VP8LPutBits(bw, pred_bits - 2, 3);
|
||||||
return 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
|
||||||
@ -951,10 +951,10 @@ static WebPEncodingError ApplyCrossColorFilter(const VP8LEncoder* const enc,
|
|||||||
|
|
||||||
VP8LColorSpaceTransform(width, height, ccolor_transform_bits, quality,
|
VP8LColorSpaceTransform(width, height, ccolor_transform_bits, quality,
|
||||||
enc->argb_, enc->transform_data_);
|
enc->argb_, enc->transform_data_);
|
||||||
VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
|
VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
|
||||||
VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM);
|
VP8LPutBits(bw, CROSS_COLOR_TRANSFORM, 2);
|
||||||
assert(ccolor_transform_bits >= 2);
|
assert(ccolor_transform_bits >= 2);
|
||||||
VP8LWriteBits(bw, 3, ccolor_transform_bits - 2);
|
VP8LPutBits(bw, ccolor_transform_bits - 2, 3);
|
||||||
return 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
|
||||||
@ -984,14 +984,14 @@ static int WriteImageSize(const WebPPicture* const pic,
|
|||||||
const int height = pic->height - 1;
|
const int height = pic->height - 1;
|
||||||
assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
|
assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
|
||||||
|
|
||||||
VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, width);
|
VP8LPutBits(bw, width, VP8L_IMAGE_SIZE_BITS);
|
||||||
VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, height);
|
VP8LPutBits(bw, height, VP8L_IMAGE_SIZE_BITS);
|
||||||
return !bw->error_;
|
return !bw->error_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
|
static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
|
||||||
VP8LWriteBits(bw, 1, has_alpha);
|
VP8LPutBits(bw, has_alpha, 1);
|
||||||
VP8LWriteBits(bw, VP8L_VERSION_BITS, VP8L_VERSION);
|
VP8LPutBits(bw, VP8L_VERSION, VP8L_VERSION_BITS);
|
||||||
return !bw->error_;
|
return !bw->error_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1160,10 +1160,10 @@ static WebPEncodingError EncodePalette(VP8LBitWriter* const bw,
|
|||||||
palette, palette_size, width, height, xbits, row);
|
palette, palette_size, width, height, xbits, row);
|
||||||
|
|
||||||
// Save palette to bitstream.
|
// Save palette to bitstream.
|
||||||
VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
|
VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
|
||||||
VP8LWriteBits(bw, 2, COLOR_INDEXING_TRANSFORM);
|
VP8LPutBits(bw, COLOR_INDEXING_TRANSFORM, 2);
|
||||||
assert(palette_size >= 1);
|
assert(palette_size >= 1);
|
||||||
VP8LWriteBits(bw, 8, palette_size - 1);
|
VP8LPutBits(bw, palette_size - 1, 8);
|
||||||
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]);
|
||||||
}
|
}
|
||||||
@ -1304,7 +1304,7 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
|
|||||||
if (err != VP8_ENC_OK) goto Error;
|
if (err != VP8_ENC_OK) goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT); // No more transforms.
|
VP8LPutBits(bw, !TRANSFORM_PRESENT, 1); // No more transforms.
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Estimate the color cache size.
|
// Estimate the color cache size.
|
||||||
@ -1435,7 +1435,7 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
|||||||
|
|
||||||
Error:
|
Error:
|
||||||
if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
VP8LBitWriterDestroy(&bw);
|
VP8LBitWriterWipeOut(&bw);
|
||||||
if (err != VP8_ENC_OK) {
|
if (err != VP8_ENC_OK) {
|
||||||
WebPEncodingSetError(picture, err);
|
WebPEncodingSetError(picture, err);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -140,19 +140,20 @@ int VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
|
|||||||
return bit;
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) {
|
void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits) {
|
||||||
int mask;
|
uint32_t mask;
|
||||||
for (mask = 1 << (nb_bits - 1); mask; mask >>= 1)
|
assert(nb_bits > 0 && nb_bits < 32);
|
||||||
|
for (mask = 1u << (nb_bits - 1); mask; mask >>= 1)
|
||||||
VP8PutBitUniform(bw, value & mask);
|
VP8PutBitUniform(bw, value & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) {
|
void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits) {
|
||||||
if (!VP8PutBitUniform(bw, value != 0))
|
if (!VP8PutBitUniform(bw, value != 0))
|
||||||
return;
|
return;
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1);
|
VP8PutBits(bw, ((-value) << 1) | 1, nb_bits + 1);
|
||||||
} else {
|
} else {
|
||||||
VP8PutValue(bw, value << 1, nb_bits + 1);
|
VP8PutBits(bw, value << 1, nb_bits + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +172,7 @@ int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
|
uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
|
||||||
VP8PutValue(bw, 0, 9 - bw->nb_bits_);
|
VP8PutBits(bw, 0, 9 - bw->nb_bits_);
|
||||||
bw->nb_bits_ = 0; // pad with zeroes
|
bw->nb_bits_ = 0; // pad with zeroes
|
||||||
Flush(bw);
|
Flush(bw);
|
||||||
return bw->buf_;
|
return bw->buf_;
|
||||||
@ -242,14 +243,14 @@ int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
|
|||||||
return VP8LBitWriterResize(bw, expected_size);
|
return VP8LBitWriterResize(bw, expected_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
|
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) {
|
||||||
if (bw != NULL) {
|
if (bw != NULL) {
|
||||||
WebPSafeFree(bw->buf_);
|
WebPSafeFree(bw->buf_);
|
||||||
memset(bw, 0, sizeof(*bw));
|
memset(bw, 0, sizeof(*bw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) {
|
void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits) {
|
||||||
assert(n_bits <= 32);
|
assert(n_bits <= 32);
|
||||||
// That's the max we can handle:
|
// That's the max we can handle:
|
||||||
assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS);
|
assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS);
|
||||||
|
@ -45,8 +45,8 @@ void VP8BitWriterWipeOut(VP8BitWriter* const bw);
|
|||||||
|
|
||||||
int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
|
int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
|
||||||
int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
|
int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
|
||||||
void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits);
|
void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits);
|
||||||
void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits);
|
void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits);
|
||||||
|
|
||||||
// Appends some bytes to the internal buffer. Data is copied.
|
// Appends some bytes to the internal buffer. Data is copied.
|
||||||
int VP8BitWriterAppend(VP8BitWriter* const bw,
|
int VP8BitWriterAppend(VP8BitWriter* const bw,
|
||||||
@ -97,19 +97,19 @@ static WEBP_INLINE size_t VP8LBitWriterNumBytes(VP8LBitWriter* const bw) {
|
|||||||
return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
|
return (bw->cur_ - bw->buf_) + ((bw->used_ + 7) >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
|
// Returns false in case of memory allocation error.
|
||||||
|
|
||||||
// Returns 0 in case of memory allocation error.
|
|
||||||
int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
|
int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
|
||||||
|
// Finalize the bitstream coding. Returns a pointer to the internal buffer.
|
||||||
void VP8LBitWriterDestroy(VP8LBitWriter* const bw);
|
uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw);
|
||||||
|
// Release any pending memory and zeroes the object.
|
||||||
|
void VP8LBitWriterWipeOut(VP8LBitWriter* const bw);
|
||||||
|
|
||||||
// This function writes bits into bytes in increasing addresses (little endian),
|
// This function writes bits into bytes in increasing addresses (little endian),
|
||||||
// and within a byte least-significant-bit first.
|
// and within a byte least-significant-bit first.
|
||||||
// This function can write up to 32 bits in one go, but VP8LBitReader can only
|
// This function can write up to 32 bits in one go, but VP8LBitReader can only
|
||||||
// read 24 bits max (VP8L_MAX_NUM_BIT_READ).
|
// read 24 bits max (VP8L_MAX_NUM_BIT_READ).
|
||||||
// VP8LBitWriter's error_ flag is set in case of memory allocation error.
|
// VP8LBitWriter's error_ flag is set in case of memory allocation error.
|
||||||
void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits);
|
void VP8LPutBits(VP8LBitWriter* const bw, uint32_t bits, int n_bits);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user