mirror of
https://github.com/webmproject/libwebp.git
synced 2025-04-18 14:56:47 +02:00
add additional '-' to //----... style comments globally instead of polluting further commits Change-Id: I951acc68b7b5384b4d6e235349b0067d1aa6fa8b
115 lines
2.8 KiB
C
115 lines
2.8 KiB
C
// Copyright 2011 Google Inc.
|
|
//
|
|
// This code is licensed under the same terms as WebM:
|
|
// Software License Agreement: http://www.webmproject.org/license/software/
|
|
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
|
|
// -----------------------------------------------------------------------------
|
|
//
|
|
// Alpha-plane compression.
|
|
//
|
|
// Author: Skal (pascal.massimino@gmail.com)
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include "vp8enci.h"
|
|
|
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
|
#include "zlib.h"
|
|
#endif
|
|
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
|
|
|
#define CHUNK_SIZE 8192
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
static int CompressAlpha(const uint8_t* data, size_t data_size,
|
|
uint8_t** output, size_t* output_size,
|
|
int algo) {
|
|
int ret = Z_OK;
|
|
z_stream strm;
|
|
unsigned char chunk[CHUNK_SIZE];
|
|
|
|
*output = NULL;
|
|
*output_size = 0;
|
|
memset(&strm, 0, sizeof(strm));
|
|
if (deflateInit(&strm, algo ? Z_BEST_SPEED : Z_BEST_COMPRESSION) != Z_OK) {
|
|
return 0;
|
|
}
|
|
strm.next_in = (unsigned char*)data;
|
|
strm.avail_in = data_size;
|
|
do {
|
|
size_t size_out;
|
|
|
|
strm.next_out = chunk;
|
|
strm.avail_out = CHUNK_SIZE;
|
|
ret = deflate(&strm, Z_FINISH);
|
|
if (ret == Z_STREAM_ERROR) {
|
|
break;
|
|
}
|
|
size_out = CHUNK_SIZE - strm.avail_out;
|
|
if (size_out) {
|
|
size_t new_size = *output_size + size_out;
|
|
uint8_t* new_output = realloc(*output, new_size);
|
|
if (new_output == NULL) {
|
|
ret = Z_MEM_ERROR;
|
|
break;
|
|
}
|
|
memcpy(new_output + *output_size, chunk, size_out);
|
|
*output_size = new_size;
|
|
*output = new_output;
|
|
}
|
|
} while (ret != Z_STREAM_END || strm.avail_out == 0);
|
|
|
|
deflateEnd(&strm);
|
|
if (ret != Z_STREAM_END) {
|
|
free(*output);
|
|
output_size = 0;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#endif /* WEBP_EXPERIMENTAL_FEATURES */
|
|
|
|
void VP8EncInitAlpha(VP8Encoder* enc) {
|
|
enc->has_alpha_ = (enc->pic_->a != NULL);
|
|
enc->alpha_data_ = NULL;
|
|
enc->alpha_data_size_ = 0;
|
|
}
|
|
|
|
void VP8EncCodeAlphaBlock(VP8EncIterator* it) {
|
|
(void)it;
|
|
// Nothing for now. We just ZLIB-compress in the end.
|
|
}
|
|
|
|
int VP8EncFinishAlpha(VP8Encoder* enc) {
|
|
if (enc->has_alpha_) {
|
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
|
const WebPPicture* pic = enc->pic_;
|
|
assert(pic->a);
|
|
if (!CompressAlpha(pic->a, pic->width * pic->height,
|
|
&enc->alpha_data_, &enc->alpha_data_size_,
|
|
enc->config_->alpha_compression)) {
|
|
return 0;
|
|
}
|
|
#endif
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void VP8EncDeleteAlpha(VP8Encoder* enc) {
|
|
free(enc->alpha_data_);
|
|
enc->alpha_data_ = NULL;
|
|
enc->alpha_data_size_ = 0;
|
|
enc->has_alpha_ = 0;
|
|
}
|
|
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
} // extern "C"
|
|
#endif
|