Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibWebP/src/enc/enc.syntax.c view on Meta::CPAN
if (part_size >= VP8_MAX_PARTITION_SIZE) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_PARTITION_OVERFLOW);
}
buf[3 * p + 0] = (part_size >> 0) & 0xff;
buf[3 * p + 1] = (part_size >> 8) & 0xff;
buf[3 * p + 2] = (part_size >> 16) & 0xff;
}
return p ? pic->writer(buf, 3 * p, pic) : 1;
}
//------------------------------------------------------------------------------
static int GeneratePartition0(VP8Encoder* const enc) {
VP8BitWriter* const bw = &enc->bw_;
const int mb_size = enc->mb_w_ * enc->mb_h_;
uint64_t pos1, pos2, pos3;
pos1 = VP8BitWriterPos(bw);
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); // clamp type
PutSegmentHeader(bw, enc);
PutFilterHeader(bw, &enc->filter_hdr_);
VP8PutBits(bw, enc->num_parts_ == 8 ? 3 :
enc->num_parts_ == 4 ? 2 :
enc->num_parts_ == 2 ? 1 : 0, 2);
PutQuant(bw, enc);
VP8PutBitUniform(bw, 0); // no proba update
VP8WriteProbas(bw, &enc->proba_);
pos2 = VP8BitWriterPos(bw);
VP8CodeIntraModes(enc);
VP8BitWriterFinish(bw);
pos3 = VP8BitWriterPos(bw);
if (enc->pic_->stats) {
enc->pic_->stats->header_bytes[0] = (int)((pos2 - pos1 + 7) >> 3);
enc->pic_->stats->header_bytes[1] = (int)((pos3 - pos2 + 7) >> 3);
enc->pic_->stats->alpha_data_size = (int)enc->alpha_data_size_;
}
if (bw->error_) {
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
}
return 1;
}
void VP8EncFreeBitWriters(VP8Encoder* const enc) {
int p;
VP8BitWriterWipeOut(&enc->bw_);
for (p = 0; p < enc->num_parts_; ++p) {
VP8BitWriterWipeOut(enc->parts_ + p);
}
}
int VP8EncWrite(VP8Encoder* const enc) {
WebPPicture* const pic = enc->pic_;
VP8BitWriter* const bw = &enc->bw_;
const int task_percent = 19;
const int percent_per_part = task_percent / enc->num_parts_;
const int final_percent = enc->percent_ + task_percent;
int ok = 0;
size_t vp8_size, pad, riff_size;
int p;
// Partition #0 with header and partition sizes
ok = GeneratePartition0(enc);
if (!ok) return 0;
// Compute VP8 size
vp8_size = VP8_FRAME_HEADER_SIZE +
VP8BitWriterSize(bw) +
3 * (enc->num_parts_ - 1);
for (p = 0; p < enc->num_parts_; ++p) {
vp8_size += VP8BitWriterSize(enc->parts_ + p);
}
pad = vp8_size & 1;
vp8_size += pad;
// Compute RIFF size
// At the minimum it is: "WEBPVP8 nnnn" + VP8 data size.
riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8_size;
if (IsVP8XNeeded(enc)) { // Add size for: VP8X header + data.
riff_size += CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
}
if (enc->has_alpha_) { // Add size for: ALPH header + data.
const uint32_t padded_alpha_size = enc->alpha_data_size_ +
(enc->alpha_data_size_ & 1);
riff_size += CHUNK_HEADER_SIZE + padded_alpha_size;
}
// Sanity check.
if (riff_size > 0xfffffffeU) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG);
}
// Emit headers and partition #0
{
const uint8_t* const part0 = VP8BitWriterBuf(bw);
const size_t size0 = VP8BitWriterSize(bw);
ok = ok && PutWebPHeaders(enc, size0, vp8_size, riff_size)
&& pic->writer(part0, size0, pic)
&& EmitPartitionsSize(enc, pic);
VP8BitWriterWipeOut(bw); // will free the internal buffer.
}
// Token partitions
for (p = 0; p < enc->num_parts_; ++p) {
const uint8_t* const buf = VP8BitWriterBuf(enc->parts_ + p);
const size_t size = VP8BitWriterSize(enc->parts_ + p);
if (size)
ok = ok && pic->writer(buf, size, pic);
VP8BitWriterWipeOut(enc->parts_ + p); // will free the internal buffer.
ok = ok && WebPReportProgress(pic, enc->percent_ + percent_per_part,
&enc->percent_);
}
// Padding byte
if (ok && pad) {
ok = PutPaddingByte(pic);
}
enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size);
ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_);
return ok;
}
//------------------------------------------------------------------------------
( run in 0.724 second using v1.01-cache-2.11-cpan-adec679a428 )