1a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Copyright 2011 Google Inc. All Rights Reserved. 27c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 30406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Use of this source code is governed by a BSD-style license 40406ce1417f76f2034833414dcecc9f56253640cVikas Arora// that can be found in the COPYING file in the root of the source 50406ce1417f76f2034833414dcecc9f56253640cVikas Arora// tree. An additional intellectual property rights grant can be found 60406ce1417f76f2034833414dcecc9f56253640cVikas Arora// in the file PATENTS. All contributing project authors may 70406ce1417f76f2034833414dcecc9f56253640cVikas Arora// be found in the AUTHORS file in the root of the source tree. 87c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// ----------------------------------------------------------------------------- 97c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 1033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// WebPPicture class basis 117c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 127c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Author: Skal (pascal.massimino@gmail.com) 137c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 14466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#include <assert.h> 157c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#include <stdlib.h> 16a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 17a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#include "src/enc/vp8i_enc.h" 18a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#include "src/dsp/dsp.h" 19a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#include "src/utils/utils.h" 208b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora 21a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 227c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// WebPPicture 23a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 247c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2533f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic int DummyWriter(const uint8_t* data, size_t data_size, 2633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora const WebPPicture* const picture) { 2733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // The following are to prevent 'unused variable' error message. 2833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora (void)data; 2933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora (void)data_size; 3033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora (void)picture; 3133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return 1; 3233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora} 33a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 3433f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraint WebPPictureInitInternal(WebPPicture* picture, int version) { 3533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) { 3633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return 0; // caller/system version mismatch! 3733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora } 3833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (picture != NULL) { 3933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora memset(picture, 0, sizeof(*picture)); 4033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->writer = DummyWriter; 4133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPEncodingSetError(picture, VP8_ENC_OK); 427c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 437c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 1; 447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 457c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 4633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora//------------------------------------------------------------------------------ 4733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora 4833f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic void WebPPictureResetBufferARGB(WebPPicture* const picture) { 49a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->memory_argb_ = NULL; 50a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->argb = NULL; 51a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->argb_stride = 0; 52a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 53a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 5433f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic void WebPPictureResetBufferYUVA(WebPPicture* const picture) { 55a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->memory_ = NULL; 56a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->y = picture->u = picture->v = picture->a = NULL; 57a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->y_stride = picture->uv_stride = 0; 58a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora picture->a_stride = 0; 59a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 60a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 6133f74dabbc7920a65ed435d7417987589febdc16Vikas Aroravoid WebPPictureResetBuffers(WebPPicture* const picture) { 6233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPPictureResetBufferARGB(picture); 6333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPPictureResetBufferYUVA(picture); 64a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 65a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 6633f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraint WebPPictureAllocARGB(WebPPicture* const picture, int width, int height) { 6733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora void* memory; 6833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora const uint64_t argb_size = (uint64_t)width * height; 69466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 7033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora assert(picture != NULL); 717c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 7233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPSafeFree(picture->memory_argb_); 7333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPPictureResetBufferARGB(picture); 747c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 7533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (width <= 0 || height <= 0) { 7633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION); 77a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 7833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // allocate a new buffer. 79a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern memory = WebPSafeMalloc(argb_size + WEBP_ALIGN_CST, sizeof(*picture->argb)); 8033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (memory == NULL) { 8133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); 82a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 8333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->memory_argb_ = memory; 84a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern picture->argb = (uint32_t*)WEBP_ALIGN(memory); 8533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->argb_stride = width; 86a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return 1; 87a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 88a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 8933f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraint WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height) { 9098a63a77eb8652c81d64b5b7c3d8a347111807caJames Zern const WebPEncCSP uv_csp = 9198a63a77eb8652c81d64b5b7c3d8a347111807caJames Zern (WebPEncCSP)((int)picture->colorspace & WEBP_CSP_UV_MASK); 9298a63a77eb8652c81d64b5b7c3d8a347111807caJames Zern const int has_alpha = (int)picture->colorspace & WEBP_CSP_ALPHA_BIT; 9333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora const int y_stride = width; 94a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern const int uv_width = (int)(((int64_t)width + 1) >> 1); 95a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern const int uv_height = (int)(((int64_t)height + 1) >> 1); 9633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora const int uv_stride = uv_width; 9733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora int a_width, a_stride; 9833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora uint64_t y_size, uv_size, a_size, total_size; 9933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora uint8_t* mem; 100466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 10133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora assert(picture != NULL); 102466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 10333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPSafeFree(picture->memory_); 10433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPPictureResetBufferYUVA(picture); 105a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 10633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (uv_csp != WEBP_YUV420) { 10733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION); 108a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 109a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 11033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // alpha 11133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora a_width = has_alpha ? width : 0; 11233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora a_stride = a_width; 11333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora y_size = (uint64_t)y_stride * height; 11433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora uv_size = (uint64_t)uv_stride * uv_height; 11533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora a_size = (uint64_t)a_stride * height; 116a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 11733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora total_size = y_size + a_size + 2 * uv_size; 118a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 11933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // Security and validation checks 120a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern if (width <= 0 || height <= 0 || // luma/alpha param error 121a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern uv_width <= 0 || uv_height <= 0) { // u/v param error 12233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION); 123a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 12433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // allocate a new buffer. 12533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora mem = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*mem)); 12633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (mem == NULL) { 12733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY); 128a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 129466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 13033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // From now on, we're in the clear, we can no longer fail... 13133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->memory_ = (void*)mem; 13233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->y_stride = y_stride; 13333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->uv_stride = uv_stride; 13433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->a_stride = a_stride; 1357c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 13633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora // TODO(skal): we could align the y/u/v planes and adjust stride. 13733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->y = mem; 13833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora mem += y_size; 1397c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 14033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->u = mem; 14133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora mem += uv_size; 14233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->v = mem; 14333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora mem += uv_size; 1447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 14533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (a_size > 0) { 14633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora picture->a = mem; 14733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora mem += a_size; 148a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 14933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora (void)mem; // makes the static analyzer happy 150466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 1; 151466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 152466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 15333f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraint WebPPictureAlloc(WebPPicture* picture) { 15433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (picture != NULL) { 15533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora const int width = picture->width; 15633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora const int height = picture->height; 157466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 15833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPPictureFree(picture); // erase previous buffer 1598b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora 16033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (!picture->use_argb) { 16133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPPictureAllocYUVA(picture, width, height); 16233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora } else { 16333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return WebPPictureAllocARGB(picture, width, height); 1648b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora } 1658b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora } 16633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora return 1; 1678b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora} 1688b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora 16933f74dabbc7920a65ed435d7417987589febdc16Vikas Aroravoid WebPPictureFree(WebPPicture* picture) { 17033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (picture != NULL) { 17133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPSafeFree(picture->memory_); 17233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPSafeFree(picture->memory_argb_); 17333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPPictureResetBuffers(picture); 174a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 1757c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 1767c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 177a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 178a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// WebPMemoryWriter: Write-to-memory 1797c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 180a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid WebPMemoryWriterInit(WebPMemoryWriter* writer) { 181a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora writer->mem = NULL; 182a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora writer->size = 0; 1837c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora writer->max_size = 0; 1847c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 1857c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 186a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint WebPMemoryWrite(const uint8_t* data, size_t data_size, 187a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora const WebPPicture* picture) { 1887c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora WebPMemoryWriter* const w = (WebPMemoryWriter*)picture->custom_ptr; 189a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora uint64_t next_size; 1907c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (w == NULL) { 1917c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 1; 1927c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 193a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora next_size = (uint64_t)w->size + data_size; 1947c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (next_size > w->max_size) { 1957c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora uint8_t* new_mem; 196a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora uint64_t next_max_size = 2ULL * w->max_size; 1977c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (next_max_size < next_size) next_max_size = next_size; 198a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (next_max_size < 8192ULL) next_max_size = 8192ULL; 199a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora new_mem = (uint8_t*)WebPSafeMalloc(next_max_size, 1); 2007c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (new_mem == NULL) { 2017c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 0; 2027c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 203a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (w->size > 0) { 204a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora memcpy(new_mem, w->mem, w->size); 2057c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 20633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPSafeFree(w->mem); 207a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora w->mem = new_mem; 208a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // down-cast is ok, thanks to WebPSafeMalloc 209a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora w->max_size = (size_t)next_max_size; 2107c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 211a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (data_size > 0) { 212a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora memcpy(w->mem + w->size, data, data_size); 213a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora w->size += data_size; 2147c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2157c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 1; 2167c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2177c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 21833f74dabbc7920a65ed435d7417987589febdc16Vikas Aroravoid WebPMemoryWriterClear(WebPMemoryWriter* writer) { 21933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora if (writer != NULL) { 22033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPSafeFree(writer->mem); 22133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora writer->mem = NULL; 22233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora writer->size = 0; 22333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora writer->max_size = 0; 2248b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora } 2258b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora} 2268b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora 227a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 228a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Simplest high-level calls: 2297c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2307c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroratypedef int (*Importer)(WebPPicture* const, const uint8_t* const, int); 2317c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 232466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic size_t Encode(const uint8_t* rgba, int width, int height, int stride, 233a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora Importer import, float quality_factor, int lossless, 234a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora uint8_t** output) { 2357c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora WebPPicture pic; 2367c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora WebPConfig config; 2377c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora WebPMemoryWriter wrt; 2387c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int ok; 2397c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2400912efc2528d03c59d45dd9bdc9ff9ec800a3fc1James Zern if (output == NULL) return 0; 2410912efc2528d03c59d45dd9bdc9ff9ec800a3fc1James Zern 2427c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality_factor) || 2437c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora !WebPPictureInit(&pic)) { 2447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 0; // shouldn't happen, except if system installation is broken 2457c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2467c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 247a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora config.lossless = !!lossless; 248a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora pic.use_argb = !!lossless; 2497c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora pic.width = width; 2507c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora pic.height = height; 2517c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora pic.writer = WebPMemoryWrite; 2527c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora pic.custom_ptr = &wrt; 253a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora WebPMemoryWriterInit(&wrt); 2547c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 255466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic); 2567c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora WebPPictureFree(&pic); 2577c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (!ok) { 25833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora WebPMemoryWriterClear(&wrt); 2597c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora *output = NULL; 2607c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 0; 2617c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 262a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora *output = wrt.mem; 263a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return wrt.size; 2647c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2657c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 266a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define ENCODE_FUNC(NAME, IMPORTER) \ 267a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorasize_t NAME(const uint8_t* in, int w, int h, int bps, float q, \ 268a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora uint8_t** out) { \ 269a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return Encode(in, w, h, bps, IMPORTER, q, 0, out); \ 2707c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2717c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2728b720228d581a84fd173b6dcb2fa295b59db489aVikas AroraENCODE_FUNC(WebPEncodeRGB, WebPPictureImportRGB) 2738b720228d581a84fd173b6dcb2fa295b59db489aVikas AroraENCODE_FUNC(WebPEncodeRGBA, WebPPictureImportRGBA) 274a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#if !defined(WEBP_REDUCE_CSP) 275a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames ZernENCODE_FUNC(WebPEncodeBGR, WebPPictureImportBGR) 2768b720228d581a84fd173b6dcb2fa295b59db489aVikas AroraENCODE_FUNC(WebPEncodeBGRA, WebPPictureImportBGRA) 277a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#endif // WEBP_REDUCE_CSP 2787c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2797c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#undef ENCODE_FUNC 2807c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 281a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define LOSSLESS_DEFAULT_QUALITY 70. 282a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define LOSSLESS_ENCODE_FUNC(NAME, IMPORTER) \ 283a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorasize_t NAME(const uint8_t* in, int w, int h, int bps, uint8_t** out) { \ 284a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return Encode(in, w, h, bps, IMPORTER, LOSSLESS_DEFAULT_QUALITY, 1, out); \ 285a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 286a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 2878b720228d581a84fd173b6dcb2fa295b59db489aVikas AroraLOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGB, WebPPictureImportRGB) 2888b720228d581a84fd173b6dcb2fa295b59db489aVikas AroraLOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGBA, WebPPictureImportRGBA) 289a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#if !defined(WEBP_REDUCE_CSP) 290a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames ZernLOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGR, WebPPictureImportBGR) 2918b720228d581a84fd173b6dcb2fa295b59db489aVikas AroraLOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGRA, WebPPictureImportBGRA) 292a187300ff9a8a7c10b1fb2ec84223fdd14e6d47bJames Zern#endif // WEBP_REDUCE_CSP 293a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 294a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#undef LOSSLESS_ENCODE_FUNC 295a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 296a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 297