1466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// Copyright 2011 Google Inc. 2466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// 3466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// This code is licensed under the same terms as WebM: 4466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// Software License Agreement: http://www.webmproject.org/license/software/ 5466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// ----------------------------------------------------------------------------- 7466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// 8466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// Alpha-plane compression. 9466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// 10466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora// Author: Skal (pascal.massimino@gmail.com) 11466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 12466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#include <assert.h> 13466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#include <stdlib.h> 14466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#include "vp8enci.h" 15466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 16466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#ifdef WEBP_EXPERIMENTAL_FEATURES 17466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#include "zlib.h" 18466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif 19466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 20466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#if defined(__cplusplus) || defined(c_plusplus) 21466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Aroraextern "C" { 22466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif 23466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 24466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#ifdef WEBP_EXPERIMENTAL_FEATURES 25466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 26466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#define CHUNK_SIZE 8192 27466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 28466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora//----------------------------------------------------------------------------- 29466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 30466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic int CompressAlpha(const uint8_t* data, size_t data_size, 31466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora uint8_t** output, size_t* output_size, 32466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora int algo) { 33466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora int ret = Z_OK; 34466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora z_stream strm; 35466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora unsigned char chunk[CHUNK_SIZE]; 36466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 37466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora *output = NULL; 38466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora *output_size = 0; 39466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora memset(&strm, 0, sizeof(strm)); 40466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (deflateInit(&strm, algo ? Z_BEST_SPEED : Z_BEST_COMPRESSION) != Z_OK) { 41466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; 42466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 43466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora strm.next_in = (unsigned char*)data; 44466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora strm.avail_in = data_size; 45466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora do { 46466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora size_t size_out; 47466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 48466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora strm.next_out = chunk; 49466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora strm.avail_out = CHUNK_SIZE; 50466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora ret = deflate(&strm, Z_FINISH); 51466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (ret == Z_STREAM_ERROR) { 52466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora break; 53466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 54466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora size_out = CHUNK_SIZE - strm.avail_out; 55466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (size_out) { 56466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora size_t new_size = *output_size + size_out; 57466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora uint8_t* new_output = realloc(*output, new_size); 58466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (new_output == NULL) { 59466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora ret = Z_MEM_ERROR; 60466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora break; 61466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 62466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora memcpy(new_output + *output_size, chunk, size_out); 63466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora *output_size = new_size; 64466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora *output = new_output; 65466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 66466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } while (ret != Z_STREAM_END || strm.avail_out == 0); 67466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 68466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora deflateEnd(&strm); 69466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (ret != Z_STREAM_END) { 70466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora free(*output); 71466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora output_size = 0; 72466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; 73466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 74466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 1; 75466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 76466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 77466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif /* WEBP_EXPERIMENTAL_FEATURES */ 78466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 79466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Aroravoid VP8EncInitAlpha(VP8Encoder* enc) { 80466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->has_alpha_ = (enc->pic_->a != NULL); 81466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->alpha_data_ = NULL; 82466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->alpha_data_size_ = 0; 83466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 84466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 85466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Aroravoid VP8EncCodeAlphaBlock(VP8EncIterator* it) { 86466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora (void)it; 87466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora // Nothing for now. We just ZLIB-compress in the end. 88466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 89466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 90466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Aroraint VP8EncFinishAlpha(VP8Encoder* enc) { 91466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (enc->has_alpha_) { 92466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#ifdef WEBP_EXPERIMENTAL_FEATURES 93466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const WebPPicture* pic = enc->pic_; 94466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora assert(pic->a); 95466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (!CompressAlpha(pic->a, pic->width * pic->height, 96466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora &enc->alpha_data_, &enc->alpha_data_size_, 97466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->config_->alpha_compression)) { 98466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; 99466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 100466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif 101466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 102466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 1; 103466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 104466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 105466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Aroravoid VP8EncDeleteAlpha(VP8Encoder* enc) { 106466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora free(enc->alpha_data_); 107466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->alpha_data_ = NULL; 108466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->alpha_data_size_ = 0; 109466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora enc->has_alpha_ = 0; 110466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 111466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 112466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#if defined(__cplusplus) || defined(c_plusplus) 113466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} // extern "C" 114466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif 115