in Extended/libwebp/src/enc/vp8l_enc.c [1821:1915]
int VP8LEncodeImage(const WebPConfig* const config,
const WebPPicture* const picture) {
int width, height;
int has_alpha;
size_t coded_size;
int percent = 0;
int initial_size;
WebPEncodingError err = VP8_ENC_OK;
VP8LBitWriter bw;
if (picture == NULL) return 0;
if (config == NULL || picture->argb == NULL) {
err = VP8_ENC_ERROR_NULL_PARAMETER;
WebPEncodingSetError(picture, err);
return 0;
}
width = picture->width;
height = picture->height;
// Initialize BitWriter with size corresponding to 16 bpp to photo images and
// 8 bpp for graphical images.
initial_size = (config->image_hint == WEBP_HINT_GRAPH) ?
width * height : width * height * 2;
if (!VP8LBitWriterInit(&bw, initial_size)) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error;
}
if (!WebPReportProgress(picture, 1, &percent)) {
UserAbort:
err = VP8_ENC_ERROR_USER_ABORT;
goto Error;
}
// Reset stats (for pure lossless coding)
if (picture->stats != NULL) {
WebPAuxStats* const stats = picture->stats;
memset(stats, 0, sizeof(*stats));
stats->PSNR[0] = 99.f;
stats->PSNR[1] = 99.f;
stats->PSNR[2] = 99.f;
stats->PSNR[3] = 99.f;
stats->PSNR[4] = 99.f;
}
// Write image size.
if (!WriteImageSize(picture, &bw)) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error;
}
has_alpha = WebPPictureHasTransparency(picture);
// Write the non-trivial Alpha flag and lossless version.
if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error;
}
if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
// Encode main image stream.
err = VP8LEncodeStream(config, picture, &bw, 1 /*use_cache*/);
if (err != VP8_ENC_OK) goto Error;
if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
// Finish the RIFF chunk.
err = WriteImage(picture, &bw, &coded_size);
if (err != VP8_ENC_OK) goto Error;
if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
#if !defined(WEBP_DISABLE_STATS)
// Save size.
if (picture->stats != NULL) {
picture->stats->coded_size += (int)coded_size;
picture->stats->lossless_size = (int)coded_size;
}
#endif
if (picture->extra_info != NULL) {
const int mb_w = (width + 15) >> 4;
const int mb_h = (height + 15) >> 4;
memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info));
}
Error:
if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
VP8LBitWriterWipeOut(&bw);
if (err != VP8_ENC_OK) {
WebPEncodingSetError(picture, err);
return 0;
}
return 1;
}