mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-25 13:18:22 +01:00
Add a WEBP_NODISCARD
Change-Id: Ice66f2aa6358474d728fb19c571edc86ed139a49
This commit is contained in:
parent
24d7f9cb6e
commit
13d9c30b2b
@ -51,6 +51,8 @@ option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
|
||||
OFF)
|
||||
set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)")
|
||||
set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
|
||||
option(WEBP_ENABLE_WUNUSED_RESULT "Add [[nodiscard]] to some functions. \
|
||||
CMake must be at least 3.21 to force C23" OFF)
|
||||
|
||||
if(WEBP_LINK_STATIC)
|
||||
if(WIN32)
|
||||
@ -163,6 +165,17 @@ endif()
|
||||
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
|
||||
if(WEBP_ENABLE_WUNUSED_RESULT)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21.0)
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
else()
|
||||
unset(CMAKE_C_STANDARD)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C>:-std=gnu2x>)
|
||||
endif()
|
||||
add_compile_options(-Wunused-result)
|
||||
add_definitions(-DWEBP_ENABLE_NODISCARD=1)
|
||||
endif()
|
||||
|
||||
# ##############################################################################
|
||||
# Android only.
|
||||
if(ANDROID)
|
||||
|
@ -98,7 +98,11 @@ int main(int argc, const char* argv[]) {
|
||||
for (i = 0; !error && i < image.num_frames; ++i) {
|
||||
W_CHAR out_file[1024];
|
||||
WebPDecBuffer buffer;
|
||||
WebPInitDecBuffer(&buffer);
|
||||
if (!WebPInitDecBuffer(&buffer)) {
|
||||
fprintf(stderr, "Cannot init dec buffer\n");
|
||||
error = 1;
|
||||
continue;
|
||||
}
|
||||
buffer.colorspace = MODE_RGBA;
|
||||
buffer.is_external_memory = 1;
|
||||
buffer.width = image.canvas_width;
|
||||
|
@ -613,7 +613,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Position iterator to last frame. Next call to HandleDisplay will wrap over.
|
||||
// We take this into account by bumping up loop_count.
|
||||
WebPDemuxGetFrame(kParams.dmux, 0, curr);
|
||||
if (!WebPDemuxGetFrame(kParams.dmux, 0, curr)) goto Error;
|
||||
if (kParams.loop_count) ++kParams.loop_count;
|
||||
|
||||
#if defined(__unix__) || defined(__CYGWIN__)
|
||||
|
@ -13,18 +13,20 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/utils/quant_levels_dec_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ALPHDecoder object.
|
||||
|
||||
// Allocates a new alpha decoder instance.
|
||||
static ALPHDecoder* ALPHNew(void) {
|
||||
WEBP_NODISCARD static ALPHDecoder* ALPHNew(void) {
|
||||
ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
||||
return dec;
|
||||
}
|
||||
@ -45,9 +47,9 @@ static void ALPHDelete(ALPHDecoder* const dec) {
|
||||
// header for alpha data stored using lossless compression.
|
||||
// Returns false in case of error in alpha header (data too short, invalid
|
||||
// compression method or filter, error in lossless header data etc).
|
||||
static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
|
||||
size_t data_size, const VP8Io* const src_io,
|
||||
uint8_t* output) {
|
||||
WEBP_NODISCARD static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
|
||||
size_t data_size, const VP8Io* const src_io,
|
||||
uint8_t* output) {
|
||||
int ok = 0;
|
||||
const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN;
|
||||
const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
|
||||
@ -79,7 +81,9 @@ static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
|
||||
}
|
||||
|
||||
// Copy the necessary parameters from src_io to io
|
||||
VP8InitIo(io);
|
||||
if (!VP8InitIo(io)) {
|
||||
return 0;
|
||||
}
|
||||
WebPInitCustomIo(NULL, io);
|
||||
io->opaque = dec;
|
||||
io->width = src_io->width;
|
||||
@ -107,7 +111,8 @@ static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
|
||||
// starting from row number 'row'. It assumes that rows up to (row - 1) have
|
||||
// already been decoded.
|
||||
// Returns false in case of bitstream error.
|
||||
static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
|
||||
WEBP_NODISCARD static int ALPHDecode(VP8Decoder* const dec, int row,
|
||||
int num_rows) {
|
||||
ALPHDecoder* const alph_dec = dec->alph_dec_;
|
||||
const int width = alph_dec->width_;
|
||||
const int height = alph_dec->io_.crop_bottom;
|
||||
@ -138,7 +143,8 @@ static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int AllocateAlphaPlane(VP8Decoder* const dec, const VP8Io* const io) {
|
||||
WEBP_NODISCARD static int AllocateAlphaPlane(VP8Decoder* const dec,
|
||||
const VP8Io* const io) {
|
||||
const int stride = io->width;
|
||||
const int height = io->crop_bottom;
|
||||
const uint64_t alpha_size = (uint64_t)stride * height;
|
||||
@ -166,9 +172,9 @@ void WebPDeallocateAlphaMemory(VP8Decoder* const dec) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Main entry point.
|
||||
|
||||
const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
||||
const VP8Io* const io,
|
||||
int row, int num_rows) {
|
||||
WEBP_NODISCARD const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
||||
const VP8Io* const io,
|
||||
int row, int num_rows) {
|
||||
const int width = io->width;
|
||||
const int height = io->crop_bottom;
|
||||
|
||||
|
@ -17,8 +17,10 @@
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/dec/vp8_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/decode.h"
|
||||
|
||||
// In append mode, buffer allocations increase as multiples of this value.
|
||||
// Needs to be a power of 2.
|
||||
@ -161,8 +163,9 @@ static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
|
||||
|
||||
// Appends data to the end of MemBuffer->buf_. It expands the allocated memory
|
||||
// size if required and also updates VP8BitReader's if new memory is allocated.
|
||||
static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
const uint8_t* const data, size_t data_size) {
|
||||
WEBP_NODISCARD static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
const uint8_t* const data,
|
||||
size_t data_size) {
|
||||
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
||||
MemBuffer* const mem = &idec->mem_;
|
||||
const int need_compressed_alpha = NeedCompressedAlpha(idec);
|
||||
@ -203,8 +206,9 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int RemapMemBuffer(WebPIDecoder* const idec,
|
||||
const uint8_t* const data, size_t data_size) {
|
||||
WEBP_NODISCARD static int RemapMemBuffer(WebPIDecoder* const idec,
|
||||
const uint8_t* const data,
|
||||
size_t data_size) {
|
||||
MemBuffer* const mem = &idec->mem_;
|
||||
const uint8_t* const old_buf = mem->buf_;
|
||||
const uint8_t* const old_start =
|
||||
@ -237,7 +241,8 @@ static void ClearMemBuffer(MemBuffer* const mem) {
|
||||
}
|
||||
}
|
||||
|
||||
static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) {
|
||||
WEBP_NODISCARD static int CheckMemBufferMode(MemBuffer* const mem,
|
||||
MemBufferMode expected) {
|
||||
if (mem->mode_ == MEM_MODE_NONE) {
|
||||
mem->mode_ = expected; // switch to the expected mode
|
||||
} else if (mem->mode_ != expected) {
|
||||
@ -248,7 +253,7 @@ static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) {
|
||||
}
|
||||
|
||||
// To be called last.
|
||||
static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
|
||||
WEBP_NODISCARD static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
|
||||
const WebPDecoderOptions* const options = idec->params_.options;
|
||||
WebPDecBuffer* const output = idec->params_.output;
|
||||
|
||||
@ -258,8 +263,10 @@ static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
|
||||
if (status != VP8_STATUS_OK) return status;
|
||||
}
|
||||
if (idec->final_output_ != NULL) {
|
||||
WebPCopyDecBufferPixels(output, idec->final_output_); // do the slow-copy
|
||||
const VP8StatusCode status = WebPCopyDecBufferPixels(
|
||||
output, idec->final_output_); // do the slow-copy
|
||||
WebPFreeDecBuffer(&idec->output_);
|
||||
if (status != VP8_STATUS_OK) return status;
|
||||
*output = *idec->final_output_;
|
||||
idec->final_output_ = NULL;
|
||||
}
|
||||
@ -288,7 +295,7 @@ static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
|
||||
static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
|
||||
if (idec->state_ == STATE_VP8_DATA) {
|
||||
// Synchronize the thread, clean-up and check for errors.
|
||||
VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
|
||||
(void)VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
|
||||
}
|
||||
idec->state_ = STATE_ERROR;
|
||||
return error;
|
||||
@ -602,8 +609,9 @@ static VP8StatusCode IDecode(WebPIDecoder* idec) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Internal constructor
|
||||
|
||||
static WebPIDecoder* NewDecoder(WebPDecBuffer* const output_buffer,
|
||||
const WebPBitstreamFeatures* const features) {
|
||||
WEBP_NODISCARD static WebPIDecoder* NewDecoder(
|
||||
WebPDecBuffer* const output_buffer,
|
||||
const WebPBitstreamFeatures* const features) {
|
||||
WebPIDecoder* idec = (WebPIDecoder*)WebPSafeCalloc(1ULL, sizeof(*idec));
|
||||
if (idec == NULL) {
|
||||
return NULL;
|
||||
@ -615,8 +623,10 @@ static WebPIDecoder* NewDecoder(WebPDecBuffer* const output_buffer,
|
||||
idec->last_mb_y_ = -1;
|
||||
|
||||
InitMemBuffer(&idec->mem_);
|
||||
WebPInitDecBuffer(&idec->output_);
|
||||
VP8InitIo(&idec->io_);
|
||||
if (!WebPInitDecBuffer(&idec->output_) || !VP8InitIo(&idec->io_)) {
|
||||
WebPSafeFree(idec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WebPResetDecParams(&idec->params_);
|
||||
if (output_buffer == NULL || WebPAvoidSlowMemory(output_buffer, features)) {
|
||||
@ -675,7 +685,8 @@ void WebPIDelete(WebPIDecoder* idec) {
|
||||
if (!idec->is_lossless_) {
|
||||
if (idec->state_ == STATE_VP8_DATA) {
|
||||
// Synchronize the thread, clean-up and check for errors.
|
||||
VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
|
||||
// TODO(vrabaud) do we care about the return result?
|
||||
(void)VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
|
||||
}
|
||||
VP8Delete((VP8Decoder*)idec->dec_);
|
||||
} else {
|
||||
@ -852,8 +863,8 @@ const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec,
|
||||
return src;
|
||||
}
|
||||
|
||||
uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
|
||||
int* width, int* height, int* stride) {
|
||||
WEBP_NODISCARD uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
|
||||
int* width, int* height, int* stride) {
|
||||
const WebPDecBuffer* const src = GetOutputBuffer(idec);
|
||||
if (src == NULL) return NULL;
|
||||
if (src->colorspace >= MODE_YUV) {
|
||||
@ -868,10 +879,10 @@ uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
|
||||
return src->u.RGBA.rgba;
|
||||
}
|
||||
|
||||
uint8_t* WebPIDecGetYUVA(const WebPIDecoder* idec, int* last_y,
|
||||
uint8_t** u, uint8_t** v, uint8_t** a,
|
||||
int* width, int* height,
|
||||
int* stride, int* uv_stride, int* a_stride) {
|
||||
WEBP_NODISCARD uint8_t* WebPIDecGetYUVA(const WebPIDecoder* idec, int* last_y,
|
||||
uint8_t** u, uint8_t** v, uint8_t** a,
|
||||
int* width, int* height, int* stride,
|
||||
int* uv_stride, int* a_stride) {
|
||||
const WebPDecBuffer* const src = GetOutputBuffer(idec);
|
||||
if (src == NULL) return NULL;
|
||||
if (src->colorspace < MODE_YUV) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define WEBP_DEC_VP8_DEC_H_
|
||||
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -108,16 +109,14 @@ struct VP8Io {
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
int VP8InitIoInternal(VP8Io* const, int);
|
||||
WEBP_NODISCARD int VP8InitIoInternal(VP8Io* const, int);
|
||||
|
||||
// Set the custom IO function pointers and user-data. The setter for IO hooks
|
||||
// should be called before initiating incremental decoding. Returns true if
|
||||
// WebPIDecoder object is successfully modified, false otherwise.
|
||||
int WebPISetIOHooks(WebPIDecoder* const idec,
|
||||
VP8IoPutHook put,
|
||||
VP8IoSetupHook setup,
|
||||
VP8IoTeardownHook teardown,
|
||||
void* user_data);
|
||||
WEBP_NODISCARD int WebPISetIOHooks(WebPIDecoder* const idec, VP8IoPutHook put,
|
||||
VP8IoSetupHook setup,
|
||||
VP8IoTeardownHook teardown, void* user_data);
|
||||
|
||||
// Main decoding object. This is an opaque structure.
|
||||
typedef struct VP8Decoder VP8Decoder;
|
||||
@ -128,17 +127,17 @@ VP8Decoder* VP8New(void);
|
||||
// Must be called to make sure 'io' is initialized properly.
|
||||
// Returns false in case of version mismatch. Upon such failure, no other
|
||||
// decoding function should be called (VP8Decode, VP8GetHeaders, ...)
|
||||
static WEBP_INLINE int VP8InitIo(VP8Io* const io) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int VP8InitIo(VP8Io* const io) {
|
||||
return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Decode the VP8 frame header. Returns true if ok.
|
||||
// Note: 'io->data' must be pointing to the start of the VP8 frame header.
|
||||
int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
|
||||
WEBP_NODISCARD int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
|
||||
|
||||
// Decode a picture. Will call VP8GetHeaders() if it wasn't done already.
|
||||
// Returns false in case of error.
|
||||
int VP8Decode(VP8Decoder* const dec, VP8Io* const io);
|
||||
WEBP_NODISCARD int VP8Decode(VP8Decoder* const dec, VP8Io* const io);
|
||||
|
||||
// Return current status of the decoder:
|
||||
VP8StatusCode VP8Status(VP8Decoder* const dec);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "src/utils/random_utils.h"
|
||||
#include "src/utils/thread_utils.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -282,7 +283,7 @@ int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec);
|
||||
void VP8ParseQuant(VP8Decoder* const dec);
|
||||
|
||||
// in frame.c
|
||||
int VP8InitFrame(VP8Decoder* const dec, VP8Io* const io);
|
||||
WEBP_NODISCARD int VP8InitFrame(VP8Decoder* const dec, VP8Io* const io);
|
||||
// Call io->setup() and finish setting up scan parameters.
|
||||
// After this call returns, one must always call VP8ExitCritical() with the
|
||||
// same parameters. Both functions should be used in pair. Returns VP8_STATUS_OK
|
||||
@ -290,7 +291,7 @@ int VP8InitFrame(VP8Decoder* const dec, VP8Io* const io);
|
||||
VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io);
|
||||
// Must always be called in pair with VP8EnterCritical().
|
||||
// Returns false in case of error.
|
||||
int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io);
|
||||
WEBP_NODISCARD int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io);
|
||||
// Return the multi-threading method to use (0=off), depending
|
||||
// on options and bitstream size. Only for lossy decoding.
|
||||
int VP8GetThreadMethod(const WebPDecoderOptions* const options,
|
||||
@ -300,11 +301,12 @@ int VP8GetThreadMethod(const WebPDecoderOptions* const options,
|
||||
void VP8InitDithering(const WebPDecoderOptions* const options,
|
||||
VP8Decoder* const dec);
|
||||
// Process the last decoded row (filtering + output).
|
||||
int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io);
|
||||
WEBP_NODISCARD int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io);
|
||||
// To be called at the start of a new scanline, to initialize predictors.
|
||||
void VP8InitScanline(VP8Decoder* const dec);
|
||||
// Decode one macroblock. Returns false if there is not enough data.
|
||||
int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br);
|
||||
WEBP_NODISCARD int VP8DecodeMB(VP8Decoder* const dec,
|
||||
VP8BitReader* const token_br);
|
||||
|
||||
// in alpha.c
|
||||
const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/utils/color_cache_utils.h"
|
||||
#include "src/utils/huffman_utils.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -99,25 +100,26 @@ struct ALPHDecoder; // Defined in dec/alphai.h.
|
||||
|
||||
// Decodes image header for alpha data stored using lossless compression.
|
||||
// Returns false in case of error.
|
||||
int VP8LDecodeAlphaHeader(struct ALPHDecoder* const alph_dec,
|
||||
const uint8_t* const data, size_t data_size);
|
||||
WEBP_NODISCARD int VP8LDecodeAlphaHeader(struct ALPHDecoder* const alph_dec,
|
||||
const uint8_t* const data,
|
||||
size_t data_size);
|
||||
|
||||
// Decodes *at least* 'last_row' rows of alpha. If some of the initial rows are
|
||||
// already decoded in previous call(s), it will resume decoding from where it
|
||||
// was paused.
|
||||
// Returns false in case of bitstream error.
|
||||
int VP8LDecodeAlphaImageStream(struct ALPHDecoder* const alph_dec,
|
||||
int last_row);
|
||||
WEBP_NODISCARD int VP8LDecodeAlphaImageStream(
|
||||
struct ALPHDecoder* const alph_dec, int last_row);
|
||||
|
||||
// Allocates and initialize a new lossless decoder instance.
|
||||
VP8LDecoder* VP8LNew(void);
|
||||
WEBP_NODISCARD VP8LDecoder* VP8LNew(void);
|
||||
|
||||
// Decodes the image header. Returns false in case of error.
|
||||
int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io);
|
||||
WEBP_NODISCARD int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io);
|
||||
|
||||
// Decodes an image. It's required to decode the lossless header before calling
|
||||
// this function. Returns false in case of error, with updated dec->status_.
|
||||
int VP8LDecodeImage(VP8LDecoder* const dec);
|
||||
WEBP_NODISCARD int VP8LDecodeImage(VP8LDecoder* const dec);
|
||||
|
||||
// Resets the decoder in its initial state, reclaiming memory.
|
||||
// Preserves the dec->status_ value.
|
||||
@ -133,11 +135,10 @@ void VP8LDelete(VP8LDecoder* const dec);
|
||||
// 'num_htree_groups' groups. If 'num_htree_groups_max' > 'num_htree_groups',
|
||||
// some of those indices map to -1. This is used for non-balanced codes to
|
||||
// limit memory usage.
|
||||
int ReadHuffmanCodesHelper(int color_cache_bits, int num_htree_groups,
|
||||
int num_htree_groups_max, const int* const mapping,
|
||||
VP8LDecoder* const dec,
|
||||
HuffmanTables* const huffman_tables,
|
||||
HTreeGroup** const htree_groups);
|
||||
WEBP_NODISCARD int ReadHuffmanCodesHelper(
|
||||
int color_cache_bits, int num_htree_groups, int num_htree_groups_max,
|
||||
const int* const mapping, VP8LDecoder* const dec,
|
||||
HuffmanTables* const huffman_tables, HTreeGroup** const htree_groups);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -13,11 +13,14 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/vp8_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/mux_types.h" // ALPHA_FLAG
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RIFF layout is:
|
||||
@ -444,8 +447,9 @@ void WebPResetDecParams(WebPDecParams* const params) {
|
||||
// "Into" decoding variants
|
||||
|
||||
// Main flow
|
||||
static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
|
||||
WebPDecParams* const params) {
|
||||
WEBP_NODISCARD static VP8StatusCode DecodeInto(const uint8_t* const data,
|
||||
size_t data_size,
|
||||
WebPDecParams* const params) {
|
||||
VP8StatusCode status;
|
||||
VP8Io io;
|
||||
WebPHeaderStructure headers;
|
||||
@ -459,7 +463,9 @@ static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
|
||||
}
|
||||
|
||||
assert(params != NULL);
|
||||
VP8InitIo(&io);
|
||||
if (!VP8InitIo(&io)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
io.data = headers.data + headers.offset;
|
||||
io.data_size = headers.data_size - headers.offset;
|
||||
WebPInitCustomIo(params, &io); // Plug the I/O functions.
|
||||
@ -523,17 +529,16 @@ static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
|
||||
}
|
||||
|
||||
// Helpers
|
||||
static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace,
|
||||
const uint8_t* const data,
|
||||
size_t data_size,
|
||||
uint8_t* const rgba,
|
||||
int stride, size_t size) {
|
||||
WEBP_NODISCARD static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace,
|
||||
const uint8_t* const data,
|
||||
size_t data_size,
|
||||
uint8_t* const rgba,
|
||||
int stride, size_t size) {
|
||||
WebPDecParams params;
|
||||
WebPDecBuffer buf;
|
||||
if (rgba == NULL) {
|
||||
if (rgba == NULL || !WebPInitDecBuffer(&buf)) {
|
||||
return NULL;
|
||||
}
|
||||
WebPInitDecBuffer(&buf);
|
||||
WebPResetDecParams(¶ms);
|
||||
params.output = &buf;
|
||||
buf.colorspace = colorspace;
|
||||
@ -578,8 +583,7 @@ uint8_t* WebPDecodeYUVInto(const uint8_t* data, size_t data_size,
|
||||
uint8_t* v, size_t v_size, int v_stride) {
|
||||
WebPDecParams params;
|
||||
WebPDecBuffer output;
|
||||
if (luma == NULL) return NULL;
|
||||
WebPInitDecBuffer(&output);
|
||||
if (luma == NULL || !WebPInitDecBuffer(&output)) return NULL;
|
||||
WebPResetDecParams(¶ms);
|
||||
params.output = &output;
|
||||
output.colorspace = MODE_YUV;
|
||||
@ -601,13 +605,17 @@ uint8_t* WebPDecodeYUVInto(const uint8_t* data, size_t data_size,
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static uint8_t* Decode(WEBP_CSP_MODE mode, const uint8_t* const data,
|
||||
size_t data_size, int* const width, int* const height,
|
||||
WebPDecBuffer* const keep_info) {
|
||||
WEBP_NODISCARD static uint8_t* Decode(WEBP_CSP_MODE mode,
|
||||
const uint8_t* const data,
|
||||
size_t data_size, int* const width,
|
||||
int* const height,
|
||||
WebPDecBuffer* const keep_info) {
|
||||
WebPDecParams params;
|
||||
WebPDecBuffer output;
|
||||
|
||||
WebPInitDecBuffer(&output);
|
||||
if (!WebPInitDecBuffer(&output)) {
|
||||
return NULL;
|
||||
}
|
||||
WebPResetDecParams(¶ms);
|
||||
params.output = &output;
|
||||
output.colorspace = mode;
|
||||
@ -733,7 +741,9 @@ int WebPInitDecoderConfigInternal(WebPDecoderConfig* config,
|
||||
}
|
||||
memset(config, 0, sizeof(*config));
|
||||
DefaultFeatures(&config->input);
|
||||
WebPInitDecBuffer(&config->output);
|
||||
if (!WebPInitDecBuffer(&config->output)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -772,7 +782,9 @@ VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
|
||||
if (WebPAvoidSlowMemory(params.output, &config->input)) {
|
||||
// decoding to slow memory: use a temporary in-mem buffer to decode into.
|
||||
WebPDecBuffer in_mem_buffer;
|
||||
WebPInitDecBuffer(&in_mem_buffer);
|
||||
if (!WebPInitDecBuffer(&in_mem_buffer)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
in_mem_buffer.colorspace = config->output.colorspace;
|
||||
in_mem_buffer.width = config->input.width;
|
||||
in_mem_buffer.height = config->input.height;
|
||||
|
@ -20,6 +20,7 @@ extern "C" {
|
||||
|
||||
#include "src/utils/rescaler_utils.h"
|
||||
#include "src/dec/vp8_dec.h"
|
||||
#include "src/webp/decode.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecParams: Decoding output parameters. Transient internal object.
|
||||
@ -87,8 +88,9 @@ void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
|
||||
|
||||
// Setup crop_xxx fields, mb_w and mb_h in io. 'src_colorspace' refers
|
||||
// to the *compressed* format, not the output one.
|
||||
int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||
VP8Io* const io, WEBP_CSP_MODE src_colorspace);
|
||||
WEBP_NODISCARD int WebPIoInitFromOptions(
|
||||
const WebPDecoderOptions* const options, VP8Io* const io,
|
||||
WEBP_CSP_MODE src_colorspace);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Internal functions regarding WebPDecBuffer memory (in buffer.c).
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/demux.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#define NUM_CHANNELS 4
|
||||
|
||||
@ -68,8 +69,9 @@ int WebPAnimDecoderOptionsInitInternal(WebPAnimDecoderOptions* dec_options,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ApplyDecoderOptions(const WebPAnimDecoderOptions* const dec_options,
|
||||
WebPAnimDecoder* const dec) {
|
||||
WEBP_NODISCARD static int ApplyDecoderOptions(
|
||||
const WebPAnimDecoderOptions* const dec_options,
|
||||
WebPAnimDecoder* const dec) {
|
||||
WEBP_CSP_MODE mode;
|
||||
WebPDecoderConfig* config = &dec->config_;
|
||||
assert(dec_options != NULL);
|
||||
@ -82,7 +84,9 @@ static int ApplyDecoderOptions(const WebPAnimDecoderOptions* const dec_options,
|
||||
dec->blend_func_ = (mode == MODE_RGBA || mode == MODE_BGRA)
|
||||
? &BlendPixelRowNonPremult
|
||||
: &BlendPixelRowPremult;
|
||||
WebPInitDecoderConfig(config);
|
||||
if (!WebPInitDecoderConfig(config)) {
|
||||
return 0;
|
||||
}
|
||||
config->output.colorspace = mode;
|
||||
config->output.is_external_memory = 1;
|
||||
config->options.use_threads = dec_options->use_threads;
|
||||
@ -157,8 +161,8 @@ static int IsFullFrame(int width, int height, int canvas_width,
|
||||
}
|
||||
|
||||
// Clear the canvas to transparent.
|
||||
static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width,
|
||||
uint32_t canvas_height) {
|
||||
WEBP_NODISCARD static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width,
|
||||
uint32_t canvas_height) {
|
||||
const uint64_t size =
|
||||
(uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
|
||||
if (!CheckSizeOverflow(size)) return 0;
|
||||
@ -179,8 +183,8 @@ static void ZeroFillFrameRect(uint8_t* buf, int buf_stride, int x_offset,
|
||||
}
|
||||
|
||||
// Copy width * height pixels from 'src' to 'dst'.
|
||||
static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
||||
uint32_t width, uint32_t height) {
|
||||
WEBP_NODISCARD static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
||||
uint32_t width, uint32_t height) {
|
||||
const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
|
||||
if (!CheckSizeOverflow(size)) return 0;
|
||||
assert(src != NULL && dst != NULL);
|
||||
@ -424,7 +428,9 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
|
||||
WebPDemuxReleaseIterator(&dec->prev_iter_);
|
||||
dec->prev_iter_ = iter;
|
||||
dec->prev_frame_was_keyframe_ = is_key_frame;
|
||||
CopyCanvas(dec->curr_frame_, dec->prev_frame_disposed_, width, height);
|
||||
if (!CopyCanvas(dec->curr_frame_, dec->prev_frame_disposed_, width, height)) {
|
||||
goto Error;
|
||||
}
|
||||
if (dec->prev_iter_.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
|
||||
ZeroFillFrameRect(dec->prev_frame_disposed_, width * NUM_CHANNELS,
|
||||
dec->prev_iter_.x_offset, dec->prev_iter_.y_offset,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/utils/filters_utils.h"
|
||||
#include "src/utils/quant_levels_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/encode.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -66,7 +67,7 @@ static int EncodeLossless(const uint8_t* const data, int width, int height,
|
||||
WebPDispatchAlphaToGreen(data, width, picture.width, picture.height,
|
||||
picture.argb, picture.argb_stride);
|
||||
|
||||
WebPConfigInit(&config);
|
||||
if (!WebPConfigInit(&config)) return 0;
|
||||
config.lossless = 1;
|
||||
// Enable exact, or it would alter RGB values of transparent alpha, which is
|
||||
// normally OK but not here since we are not encoding the input image but an
|
||||
|
@ -1675,7 +1675,9 @@ int VP8LEncodeStream(const WebPConfig* const config,
|
||||
}
|
||||
|
||||
// Avoid "garbage value" error from Clang's static analysis tool.
|
||||
WebPPictureInit(&picture_side);
|
||||
if (!WebPPictureInit(&picture_side)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Analyze image (entropy, num_palettes etc)
|
||||
if (!EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "src/webp/encode.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "src/webp/mux.h"
|
||||
#include "src/webp/types.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
@ -1398,7 +1399,10 @@ int WebPAnimEncoderAdd(WebPAnimEncoder* enc, WebPPicture* frame, int timestamp,
|
||||
}
|
||||
config = *encoder_config;
|
||||
} else {
|
||||
WebPConfigInit(&config);
|
||||
if (!WebPConfigInit(&config)) {
|
||||
MarkError(enc, "Cannot Init config");
|
||||
return 0;
|
||||
}
|
||||
config.lossless = 1;
|
||||
}
|
||||
assert(enc->curr_canvas_ == NULL);
|
||||
@ -1419,12 +1423,14 @@ int WebPAnimEncoderAdd(WebPAnimEncoder* enc, WebPPicture* frame, int timestamp,
|
||||
// -----------------------------------------------------------------------------
|
||||
// Bitstream assembly.
|
||||
|
||||
static int DecodeFrameOntoCanvas(const WebPMuxFrameInfo* const frame,
|
||||
WebPPicture* const canvas) {
|
||||
WEBP_NODISCARD static int DecodeFrameOntoCanvas(
|
||||
const WebPMuxFrameInfo* const frame, WebPPicture* const canvas) {
|
||||
const WebPData* const image = &frame->bitstream;
|
||||
WebPPicture sub_image;
|
||||
WebPDecoderConfig config;
|
||||
WebPInitDecoderConfig(&config);
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
return 0;
|
||||
}
|
||||
WebPUtilClearPic(canvas, NULL);
|
||||
if (WebPGetFeatures(image->bytes, image->size, &config.input) !=
|
||||
VP8_STATUS_OK) {
|
||||
|
@ -63,7 +63,8 @@ typedef struct HuffmanTables {
|
||||
|
||||
// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on
|
||||
// memory allocation error, 1 otherwise.
|
||||
int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
|
||||
WEBP_NODISCARD int VP8LHuffmanTablesAllocate(int size,
|
||||
HuffmanTables* huffman_tables);
|
||||
void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
|
||||
|
||||
#define HUFFMAN_PACKED_BITS 6
|
||||
@ -91,7 +92,7 @@ struct HTreeGroup {
|
||||
};
|
||||
|
||||
// Creates the instance of HTreeGroup with specified number of tree-groups.
|
||||
HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups);
|
||||
WEBP_NODISCARD HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups);
|
||||
|
||||
// Releases the memory allocated for HTreeGroup.
|
||||
void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
|
||||
@ -101,8 +102,10 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
|
||||
// the huffman table.
|
||||
// Returns built table size or 0 in case of error (invalid tree or
|
||||
// memory error).
|
||||
int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
|
||||
const int code_lengths[], int code_lengths_size);
|
||||
WEBP_NODISCARD int VP8LBuildHuffmanTable(HuffmanTables* const root_table,
|
||||
int root_bits,
|
||||
const int code_lengths[],
|
||||
int code_lengths_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -48,34 +48,33 @@ WEBP_EXTERN int WebPGetDecoderVersion(void);
|
||||
// RIFF + VP8X + (optional chunks) + VP8(L)
|
||||
// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
|
||||
// VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
|
||||
WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPGetInfo(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height);
|
||||
|
||||
// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
|
||||
// with the dimensions in *width and *height. The ordering of samples in
|
||||
// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
|
||||
// The returned pointer should be deleted calling WebPFree().
|
||||
// Returns NULL in case of error.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGBA(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeARGB(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGRA(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
|
||||
// If the bitstream contains transparency, it is ignored.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGB(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGR(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height);
|
||||
|
||||
// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
|
||||
// returned is the Y samples buffer. Upon return, *u and *v will point to
|
||||
@ -87,10 +86,9 @@ WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
|
||||
// 'width' and 'height' may be NULL, the other pointers must not be.
|
||||
// Returns NULL in case of error.
|
||||
// (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr
|
||||
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height,
|
||||
uint8_t** u, uint8_t** v,
|
||||
int* stride, int* uv_stride);
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeYUV(
|
||||
const uint8_t* data, size_t data_size, int* width, int* height,
|
||||
uint8_t** u, uint8_t** v, int* stride, int* uv_stride);
|
||||
|
||||
// These five functions are variants of the above ones, that decode the image
|
||||
// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
|
||||
@ -100,22 +98,22 @@ WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
|
||||
// The parameter 'output_stride' specifies the distance (in bytes)
|
||||
// between scanlines. Hence, output_buffer_size is expected to be at least
|
||||
// output_stride x picture-height.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGBAInto(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGBAInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
WEBP_EXTERN uint8_t* WebPDecodeARGBInto(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeARGBInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGRAInto(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGRAInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
// RGB and BGR variants. Here too the transparency information, if present,
|
||||
// will be dropped and ignored.
|
||||
WEBP_EXTERN uint8_t* WebPDecodeRGBInto(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGBInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
WEBP_EXTERN uint8_t* WebPDecodeBGRInto(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGRInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
@ -126,7 +124,7 @@ WEBP_EXTERN uint8_t* WebPDecodeBGRInto(
|
||||
// 'u_size' and 'v_size' respectively.
|
||||
// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
|
||||
// during decoding (or because some buffers were found to be too small).
|
||||
WEBP_EXTERN uint8_t* WebPDecodeYUVInto(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeYUVInto(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* luma, size_t luma_size, int luma_stride,
|
||||
uint8_t* u, size_t u_size, int u_stride,
|
||||
@ -217,11 +215,11 @@ struct WebPDecBuffer {
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int);
|
||||
|
||||
// Initialize the structure as empty. Must be called before any other use.
|
||||
// Returns false in case of version mismatch
|
||||
static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
|
||||
return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -232,7 +230,7 @@ WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer);
|
||||
//------------------------------------------------------------------------------
|
||||
// Enumeration of the status codes
|
||||
|
||||
typedef enum VP8StatusCode {
|
||||
typedef enum WEBP_NODISCARD VP8StatusCode {
|
||||
VP8_STATUS_OK = 0,
|
||||
VP8_STATUS_OUT_OF_MEMORY,
|
||||
VP8_STATUS_INVALID_PARAM,
|
||||
@ -282,7 +280,8 @@ typedef enum VP8StatusCode {
|
||||
// within valid bounds.
|
||||
// All other fields of WebPDecBuffer MUST remain constant between calls.
|
||||
// Returns NULL if the allocation failed.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer);
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewDecoder(
|
||||
WebPDecBuffer* output_buffer);
|
||||
|
||||
// This function allocates and initializes an incremental-decoder object, which
|
||||
// will output the RGB/A samples specified by 'csp' into a preallocated
|
||||
@ -294,7 +293,7 @@ WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer);
|
||||
// colorspace 'csp' is taken into account for allocating this buffer. All other
|
||||
// parameters are ignored.
|
||||
// Returns NULL if the allocation failed, or if some parameters are invalid.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewRGB(
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewRGB(
|
||||
WEBP_CSP_MODE csp,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
@ -309,7 +308,7 @@ WEBP_EXTERN WebPIDecoder* WebPINewRGB(
|
||||
// In this case, the output buffer will be automatically allocated (using
|
||||
// MODE_YUVA) when decoding starts. All parameters are then ignored.
|
||||
// Returns NULL if the allocation failed or if a parameter is invalid.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewYUVA(
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewYUVA(
|
||||
uint8_t* luma, size_t luma_size, int luma_stride,
|
||||
uint8_t* u, size_t u_size, int u_stride,
|
||||
uint8_t* v, size_t v_size, int v_stride,
|
||||
@ -317,7 +316,7 @@ WEBP_EXTERN WebPIDecoder* WebPINewYUVA(
|
||||
|
||||
// Deprecated version of the above, without the alpha plane.
|
||||
// Kept for backward compatibility.
|
||||
WEBP_EXTERN WebPIDecoder* WebPINewYUV(
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewYUV(
|
||||
uint8_t* luma, size_t luma_size, int luma_stride,
|
||||
uint8_t* u, size_t u_size, int u_stride,
|
||||
uint8_t* v, size_t v_size, int v_stride);
|
||||
@ -347,21 +346,21 @@ WEBP_EXTERN VP8StatusCode WebPIUpdate(
|
||||
// (*last_y, *width etc.) can be NULL if corresponding information is not
|
||||
// needed. The values in these pointers are only valid on successful (non-NULL)
|
||||
// return.
|
||||
WEBP_EXTERN uint8_t* WebPIDecGetRGB(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPIDecGetRGB(
|
||||
const WebPIDecoder* idec, int* last_y,
|
||||
int* width, int* height, int* stride);
|
||||
|
||||
// Same as above function to get a YUVA image. Returns pointer to the luma
|
||||
// plane or NULL in case of error. If there is no alpha information
|
||||
// the alpha pointer '*a' will be returned NULL.
|
||||
WEBP_EXTERN uint8_t* WebPIDecGetYUVA(
|
||||
WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPIDecGetYUVA(
|
||||
const WebPIDecoder* idec, int* last_y,
|
||||
uint8_t** u, uint8_t** v, uint8_t** a,
|
||||
int* width, int* height, int* stride, int* uv_stride, int* a_stride);
|
||||
|
||||
// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
|
||||
// alpha information (if present). Kept for backward compatibility.
|
||||
static WEBP_INLINE uint8_t* WebPIDecGetYUV(
|
||||
WEBP_NODISCARD static WEBP_INLINE uint8_t* WebPIDecGetYUV(
|
||||
const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
|
||||
int* width, int* height, int* stride, int* uv_stride) {
|
||||
return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
|
||||
@ -374,7 +373,7 @@ static WEBP_INLINE uint8_t* WebPIDecGetYUV(
|
||||
// Returns NULL in case the incremental decoder object is in an invalid state.
|
||||
// Otherwise returns the pointer to the internal representation. This structure
|
||||
// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
|
||||
WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea(
|
||||
WEBP_NODISCARD WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea(
|
||||
const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -469,12 +468,14 @@ struct WebPDecoderConfig {
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*,
|
||||
int);
|
||||
|
||||
// Initialize the configuration as empty. This function must always be
|
||||
// called first, unless WebPGetFeatures() is to be called.
|
||||
// Returns false in case of mismatched version.
|
||||
static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPInitDecoderConfig(
|
||||
WebPDecoderConfig* config) {
|
||||
return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -489,8 +490,8 @@ static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
|
||||
// The return WebPIDecoder object must always be deleted calling WebPIDelete().
|
||||
// Returns NULL in case of error (and config->status will then reflect
|
||||
// the error condition, if available).
|
||||
WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* config);
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPIDecode(
|
||||
const uint8_t* data, size_t data_size, WebPDecoderConfig* config);
|
||||
|
||||
// Non-incremental version. This version decodes the full data at once, taking
|
||||
// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
#include "./decode.h" // for WEBP_CSP_MODE
|
||||
#include "./mux_types.h"
|
||||
#include "./types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -85,13 +86,13 @@ typedef enum WebPDemuxState {
|
||||
} WebPDemuxState;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN WebPDemuxer* WebPDemuxInternal(
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPDemuxer* WebPDemuxInternal(
|
||||
const WebPData*, int, WebPDemuxState*, int);
|
||||
|
||||
// Parses the full WebP file given by 'data'. For single images the WebP file
|
||||
// header alone or the file header and the chunk header may be absent.
|
||||
// Returns a WebPDemuxer object on successful parse, NULL otherwise.
|
||||
static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
|
||||
WEBP_NODISCARD static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
|
||||
return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -103,7 +104,7 @@ static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
|
||||
// If this data is volatile, the demuxer object should be deleted (by calling
|
||||
// WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.
|
||||
// This is usually an inexpensive operation.
|
||||
static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
|
||||
WEBP_NODISCARD static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
|
||||
const WebPData* data, WebPDemuxState* state) {
|
||||
return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
|
||||
}
|
||||
@ -164,14 +165,14 @@ struct WebPIterator {
|
||||
// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
|
||||
// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
|
||||
// NOTE: 'dmux' must persist for the lifetime of 'iter'.
|
||||
WEBP_EXTERN int WebPDemuxGetFrame(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPDemuxGetFrame(
|
||||
const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
|
||||
|
||||
// Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or
|
||||
// previous ('iter->frame_num' - 1) frame. These functions do not loop.
|
||||
// Returns true on success, false otherwise.
|
||||
WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter);
|
||||
WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter);
|
||||
|
||||
// Releases any memory associated with 'iter'.
|
||||
// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
|
||||
@ -202,15 +203,16 @@ struct WebPChunkIterator {
|
||||
// payloads are accessed through WebPDemuxGetFrame() and related functions.
|
||||
// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
|
||||
// NOTE: 'dmux' must persist for the lifetime of the iterator.
|
||||
WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux,
|
||||
const char fourcc[4], int chunk_number,
|
||||
WebPChunkIterator* iter);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux,
|
||||
const char fourcc[4],
|
||||
int chunk_number,
|
||||
WebPChunkIterator* iter);
|
||||
|
||||
// Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous
|
||||
// ('iter->chunk_num' - 1) chunk. These functions do not loop.
|
||||
// Returns true on success, false otherwise.
|
||||
WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter);
|
||||
WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter);
|
||||
|
||||
// Releases any memory associated with 'iter'.
|
||||
// Must be called before destroying the associated WebPDemuxer with
|
||||
@ -257,21 +259,21 @@ struct WebPAnimDecoderOptions {
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point.
|
||||
WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal(
|
||||
WebPAnimDecoderOptions*, int);
|
||||
|
||||
// Should always be called, to initialize a fresh WebPAnimDecoderOptions
|
||||
// structure before modification. Returns false in case of version mismatch.
|
||||
// WebPAnimDecoderOptionsInit() must have succeeded before using the
|
||||
// 'dec_options' object.
|
||||
static WEBP_INLINE int WebPAnimDecoderOptionsInit(
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPAnimDecoderOptionsInit(
|
||||
WebPAnimDecoderOptions* dec_options) {
|
||||
return WebPAnimDecoderOptionsInitInternal(dec_options,
|
||||
WEBP_DEMUX_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Internal, version-checked, entry point.
|
||||
WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal(
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal(
|
||||
const WebPData*, const WebPAnimDecoderOptions*, int);
|
||||
|
||||
// Creates and initializes a WebPAnimDecoder object.
|
||||
@ -284,7 +286,7 @@ WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal(
|
||||
// Returns:
|
||||
// A pointer to the newly created WebPAnimDecoder object, or NULL in case of
|
||||
// parsing error, invalid option or memory error.
|
||||
static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew(
|
||||
WEBP_NODISCARD static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew(
|
||||
const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) {
|
||||
return WebPAnimDecoderNewInternal(webp_data, dec_options,
|
||||
WEBP_DEMUX_ABI_VERSION);
|
||||
@ -306,8 +308,8 @@ struct WebPAnimInfo {
|
||||
// info - (out) global information fetched from the animation.
|
||||
// Returns:
|
||||
// True on success.
|
||||
WEBP_EXTERN int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec,
|
||||
WebPAnimInfo* info);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderGetInfo(
|
||||
const WebPAnimDecoder* dec, WebPAnimInfo* info);
|
||||
|
||||
// Fetch the next frame from 'dec' based on options supplied to
|
||||
// WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size
|
||||
@ -321,8 +323,9 @@ WEBP_EXTERN int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec,
|
||||
// Returns:
|
||||
// False if any of the arguments are NULL, or if there is a parsing or
|
||||
// decoding error, or if there are no more frames. Otherwise, returns true.
|
||||
WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
|
||||
uint8_t** buf, int* timestamp);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
|
||||
uint8_t** buf,
|
||||
int* timestamp);
|
||||
|
||||
// Check if there are more frames left to decode.
|
||||
// Parameters:
|
||||
@ -330,7 +333,8 @@ WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
|
||||
// Returns:
|
||||
// True if 'dec' is not NULL and some frames are yet to be decoded.
|
||||
// Otherwise, returns false.
|
||||
WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(
|
||||
const WebPAnimDecoder* dec);
|
||||
|
||||
// Resets the WebPAnimDecoder object, so that next call to
|
||||
// WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be
|
||||
@ -348,7 +352,7 @@ WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec);
|
||||
//
|
||||
// Parameters:
|
||||
// dec - (in) decoder instance from which the demuxer object is to be fetched.
|
||||
WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer(
|
||||
WEBP_NODISCARD WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer(
|
||||
const WebPAnimDecoder* dec);
|
||||
|
||||
// Deletes the WebPAnimDecoder object.
|
||||
|
@ -164,13 +164,14 @@ typedef enum WebPPreset {
|
||||
} WebPPreset;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset,
|
||||
float, int);
|
||||
|
||||
// Should always be called, to initialize a fresh WebPConfig structure before
|
||||
// modification. Returns false in case of version mismatch. WebPConfigInit()
|
||||
// must have succeeded before using the 'config' object.
|
||||
// Note that the default values are lossless=0 and quality=75.
|
||||
static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
|
||||
return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
|
||||
WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
@ -179,8 +180,9 @@ static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
|
||||
// set of parameters (referred to by 'preset') and a given quality factor.
|
||||
// This function can be called as a replacement to WebPConfigInit(). Will
|
||||
// return false in case of error.
|
||||
static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
|
||||
WebPPreset preset, float quality) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
|
||||
WebPPreset preset,
|
||||
float quality) {
|
||||
return WebPConfigInitInternal(config, preset, quality,
|
||||
WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
@ -191,11 +193,12 @@ static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
|
||||
// speed and final compressed size.
|
||||
// This function will overwrite several fields from config: 'method', 'quality'
|
||||
// and 'lossless'. Returns false in case of parameter error.
|
||||
WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config,
|
||||
int level);
|
||||
|
||||
// Returns true if 'config' is non-NULL and all configuration parameters are
|
||||
// within their valid ranges.
|
||||
WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Input / Output
|
||||
@ -255,8 +258,8 @@ WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer);
|
||||
// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
|
||||
// completion, writer.mem and writer.size will hold the coded data.
|
||||
// writer.mem must be freed by calling WebPMemoryWriterClear.
|
||||
WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* picture);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPMemoryWrite(
|
||||
const uint8_t* data, size_t data_size, const WebPPicture* picture);
|
||||
|
||||
// Progress hook, called from time to time to report progress. It can return
|
||||
// false to request an abort of the encoding process, or true otherwise if
|
||||
@ -364,13 +367,13 @@ struct WebPPicture {
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int);
|
||||
|
||||
// Should always be called, to initialize the structure. Returns false in case
|
||||
// of version mismatch. WebPPictureInit() must have succeeded before using the
|
||||
// 'picture' object.
|
||||
// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
|
||||
static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
|
||||
return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -381,7 +384,7 @@ static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
|
||||
// Allocate y/u/v buffers as per colorspace/width/height specification.
|
||||
// Note! This function will free the previous buffer if needed.
|
||||
// Returns false in case of memory error.
|
||||
WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture);
|
||||
|
||||
// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
|
||||
// Note that this function does _not_ free the memory used by the 'picture'
|
||||
@ -394,7 +397,8 @@ WEBP_EXTERN void WebPPictureFree(WebPPicture* picture);
|
||||
// will fully own the copied pixels (this is not a view). The 'dst' picture need
|
||||
// not be initialized as its content is overwritten.
|
||||
// Returns false in case of memory allocation error.
|
||||
WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src,
|
||||
WebPPicture* dst);
|
||||
|
||||
// Compute the single distortion for packed planes of samples.
|
||||
// 'src' will be compared to 'ref', and the raw distortion stored into
|
||||
@ -403,19 +407,18 @@ WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
|
||||
// 'x_step' is the horizontal stride (in bytes) between samples.
|
||||
// 'src/ref_stride' is the byte distance between rows.
|
||||
// Returns false in case of error (bad parameter, memory allocation error, ...).
|
||||
WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride,
|
||||
const uint8_t* ref, size_t ref_stride,
|
||||
int width, int height,
|
||||
size_t x_step,
|
||||
int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
|
||||
float* distortion, float* result);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPlaneDistortion(
|
||||
const uint8_t* src, size_t src_stride,
|
||||
const uint8_t* ref, size_t ref_stride, int width, int height, size_t x_step,
|
||||
int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
|
||||
float* distortion, float* result);
|
||||
|
||||
// Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results
|
||||
// are in dB, stored in result[] in the B/G/R/A/All order. The distortion is
|
||||
// always performed using ARGB samples. Hence if the input is YUV(A), the
|
||||
// picture will be internally converted to ARGB (just for the measurement).
|
||||
// Warning: this function is rather CPU-intensive.
|
||||
WEBP_EXTERN int WebPPictureDistortion(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureDistortion(
|
||||
const WebPPicture* src, const WebPPicture* ref,
|
||||
int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
|
||||
float result[5]);
|
||||
@ -428,8 +431,8 @@ WEBP_EXTERN int WebPPictureDistortion(
|
||||
// must be fully be comprised inside the 'src' source picture. If the source
|
||||
// picture uses the YUV420 colorspace, the top and left coordinates will be
|
||||
// snapped to even values.
|
||||
WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture,
|
||||
int left, int top, int width, int height);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureCrop(
|
||||
WebPPicture* picture, int left, int top, int width, int height);
|
||||
|
||||
// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
|
||||
// is defined by the top-left corner pixel coordinates (left, top) as well
|
||||
@ -442,9 +445,9 @@ WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture,
|
||||
// with WebPPictureInit() if it is different from 'src', since its content will
|
||||
// be overwritten.
|
||||
// Returns false in case of invalid parameters.
|
||||
WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
|
||||
int left, int top, int width, int height,
|
||||
WebPPicture* dst);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureView(
|
||||
const WebPPicture* src, int left, int top, int width, int height,
|
||||
WebPPicture* dst);
|
||||
|
||||
// Returns true if the 'picture' is actually a view and therefore does
|
||||
// not own the memory for pixels.
|
||||
@ -455,29 +458,30 @@ WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture);
|
||||
// dimension will be calculated preserving the aspect ratio.
|
||||
// No gamma correction is applied.
|
||||
// Returns false in case of error (invalid parameter or insufficient memory).
|
||||
WEBP_EXTERN int WebPPictureRescale(WebPPicture* picture, int width, int height);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureRescale(WebPPicture* picture,
|
||||
int width, int height);
|
||||
|
||||
// Colorspace conversion function to import RGB samples.
|
||||
// Previous buffer will be free'd, if any.
|
||||
// *rgb buffer should have a size of at least height * rgb_stride.
|
||||
// Returns false in case of memory error.
|
||||
WEBP_EXTERN int WebPPictureImportRGB(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureImportRGB(
|
||||
WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
|
||||
// Same, but for RGBA buffer.
|
||||
WEBP_EXTERN int WebPPictureImportRGBA(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureImportRGBA(
|
||||
WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
|
||||
// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
|
||||
// input buffer ignoring the alpha channel. Avoids needing to copy the data
|
||||
// to a temporary 24-bit RGB buffer to import the RGB only.
|
||||
WEBP_EXTERN int WebPPictureImportRGBX(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureImportRGBX(
|
||||
WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
|
||||
|
||||
// Variants of the above, but taking BGR(A|X) input.
|
||||
WEBP_EXTERN int WebPPictureImportBGR(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureImportBGR(
|
||||
WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
|
||||
WEBP_EXTERN int WebPPictureImportBGRA(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureImportBGRA(
|
||||
WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
|
||||
WEBP_EXTERN int WebPPictureImportBGRX(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureImportBGRX(
|
||||
WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
|
||||
|
||||
// Converts picture->argb data to the YUV420A format. The 'colorspace'
|
||||
@ -486,24 +490,24 @@ WEBP_EXTERN int WebPPictureImportBGRX(
|
||||
// non-opaque transparent values is detected, and 'colorspace' will be
|
||||
// adjusted accordingly. Note that this method is lossy.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture,
|
||||
WebPEncCSP /*colorspace = WEBP_YUV420*/);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureARGBToYUVA(
|
||||
WebPPicture* picture, WebPEncCSP /*colorspace = WEBP_YUV420*/);
|
||||
|
||||
// Same as WebPPictureARGBToYUVA(), but the conversion is done using
|
||||
// pseudo-random dithering with a strength 'dithering' between
|
||||
// 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
|
||||
// for photographic picture.
|
||||
WEBP_EXTERN int WebPPictureARGBToYUVADithered(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureARGBToYUVADithered(
|
||||
WebPPicture* picture, WebPEncCSP colorspace, float dithering);
|
||||
|
||||
// Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion.
|
||||
// Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion
|
||||
// Downsampling is handled with extra care in case of color clipping. This
|
||||
// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
|
||||
// and sharper YUV representation.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture);
|
||||
// kept for backward compatibility:
|
||||
WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture);
|
||||
|
||||
// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
|
||||
// The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to
|
||||
@ -511,7 +515,7 @@ WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture);
|
||||
// Note that the use of this colorspace is discouraged if one has access to the
|
||||
// raw ARGB samples, since using YUV420 is comparatively lossy.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture);
|
||||
|
||||
// Helper function: given a width x height plane of RGBA or YUV(A) samples
|
||||
// clean-up or smoothen the YUV or RGB samples under fully transparent area,
|
||||
@ -541,7 +545,8 @@ WEBP_EXTERN void WebPBlendAlpha(WebPPicture* picture, uint32_t background_rgb);
|
||||
// the former for lossy encoding, and the latter for lossless encoding
|
||||
// (when config.lossless is true). Automatic conversion from one format to
|
||||
// another is provided but they both incur some loss.
|
||||
WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPEncode(const WebPConfig* config,
|
||||
WebPPicture* picture);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define WEBP_WEBP_MUX_H_
|
||||
|
||||
#include "./mux_types.h"
|
||||
#include "./types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -70,7 +71,7 @@ typedef struct WebPMuxAnimParams WebPMuxAnimParams;
|
||||
typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions;
|
||||
|
||||
// Error codes
|
||||
typedef enum WebPMuxError {
|
||||
typedef enum WEBP_NODISCARD WebPMuxError {
|
||||
WEBP_MUX_OK = 1,
|
||||
WEBP_MUX_NOT_FOUND = 0,
|
||||
WEBP_MUX_INVALID_ARGUMENT = -1,
|
||||
@ -104,13 +105,13 @@ WEBP_EXTERN int WebPGetMuxVersion(void);
|
||||
// Life of a Mux object
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN WebPMux* WebPNewInternal(int);
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPMux* WebPNewInternal(int);
|
||||
|
||||
// Creates an empty mux object.
|
||||
// Returns:
|
||||
// A pointer to the newly created empty mux object.
|
||||
// Or NULL in case of memory error.
|
||||
static WEBP_INLINE WebPMux* WebPMuxNew(void) {
|
||||
WEBP_NODISCARD static WEBP_INLINE WebPMux* WebPMuxNew(void) {
|
||||
return WebPNewInternal(WEBP_MUX_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -123,7 +124,8 @@ WEBP_EXTERN void WebPMuxDelete(WebPMux* mux);
|
||||
// Mux creation.
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int, int);
|
||||
WEBP_NODISCARD WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int,
|
||||
int);
|
||||
|
||||
// Creates a mux object from raw data given in WebP RIFF format.
|
||||
// Parameters:
|
||||
@ -133,8 +135,8 @@ WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int, int);
|
||||
// Returns:
|
||||
// A pointer to the mux object created from given data - on success.
|
||||
// NULL - In case of invalid data or memory error.
|
||||
static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
|
||||
int copy_data) {
|
||||
WEBP_NODISCARD static WEBP_INLINE WebPMux* WebPMuxCreate(
|
||||
const WebPData* bitstream, int copy_data) {
|
||||
return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -449,7 +451,7 @@ WEBP_EXTERN int WebPAnimEncoderOptionsInitInternal(
|
||||
// structure before modification. Returns false in case of version mismatch.
|
||||
// WebPAnimEncoderOptionsInit() must have succeeded before using the
|
||||
// 'enc_options' object.
|
||||
static WEBP_INLINE int WebPAnimEncoderOptionsInit(
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPAnimEncoderOptionsInit(
|
||||
WebPAnimEncoderOptions* enc_options) {
|
||||
return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION);
|
||||
}
|
||||
@ -490,7 +492,7 @@ static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew(
|
||||
// Returns:
|
||||
// On error, returns false and frame->error_code is set appropriately.
|
||||
// Otherwise, returns true.
|
||||
WEBP_EXTERN int WebPAnimEncoderAdd(
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPAnimEncoderAdd(
|
||||
WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms,
|
||||
const struct WebPConfig* config);
|
||||
|
||||
@ -503,8 +505,8 @@ WEBP_EXTERN int WebPAnimEncoderAdd(
|
||||
// webp_data - (out) generated WebP bitstream.
|
||||
// Returns:
|
||||
// True on success.
|
||||
WEBP_EXTERN int WebPAnimEncoderAssemble(WebPAnimEncoder* enc,
|
||||
WebPData* webp_data);
|
||||
WEBP_NODISCARD WEBP_EXTERN int WebPAnimEncoderAssemble(WebPAnimEncoder* enc,
|
||||
WebPData* webp_data);
|
||||
|
||||
// Get error string corresponding to the most recent call using 'enc'. The
|
||||
// returned string is owned by 'enc' and is valid only until the next call to
|
||||
|
@ -79,7 +79,8 @@ static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
|
||||
|
||||
// Allocates necessary storage for 'dst' and copies the contents of 'src'.
|
||||
// Returns true on success.
|
||||
static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
|
||||
WEBP_NODISCARD static WEBP_INLINE int WebPDataCopy(const WebPData* src,
|
||||
WebPData* dst) {
|
||||
if (src == NULL || dst == NULL) return 0;
|
||||
WebPDataInit(dst);
|
||||
if (src->bytes != NULL && src->size != 0) {
|
||||
|
@ -36,6 +36,23 @@ typedef long long int int64_t;
|
||||
#define WEBP_INLINE __forceinline
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#if defined(WEBP_ENABLE_NODISCARD) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201700L) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
|
||||
#define WEBP_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
// gcc's __has_attribute does not work for enums.
|
||||
#if defined(__clang__) && defined(__has_attribute)
|
||||
#if __has_attribute(warn_unused_result)
|
||||
#define WEBP_NODISCARD __attribute__((warn_unused_result))
|
||||
#else
|
||||
#define WEBP_NODISCARD
|
||||
#endif
|
||||
#else
|
||||
#define WEBP_NODISCARD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WEBP_EXTERN
|
||||
// This explicitly marks library functions and allows for changing the
|
||||
// signature for e.g., Windows DLL builds.
|
||||
@ -60,7 +77,7 @@ extern "C" {
|
||||
// Allocates 'size' bytes of memory. Returns NULL upon error. Memory
|
||||
// must be deallocated by calling WebPFree(). This function is made available
|
||||
// by the core 'libwebp' library.
|
||||
WEBP_EXTERN void* WebPMalloc(size_t size);
|
||||
WEBP_NODISCARD WEBP_EXTERN void* WebPMalloc(size_t size);
|
||||
|
||||
// Releases memory returned by the WebPDecode*() functions (from decode.h).
|
||||
WEBP_EXTERN void WebPFree(void* ptr);
|
||||
|
@ -130,7 +130,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
|
||||
}
|
||||
WebPIDelete(idec);
|
||||
} else {
|
||||
WebPDecode(data, size, &config);
|
||||
(void)WebPDecode(data, size, &config);
|
||||
}
|
||||
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
|
@ -52,9 +52,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
|
||||
if (num_htree_groups == 0) goto Error;
|
||||
// This variable is only useful when mapping is not NULL.
|
||||
const int num_htree_groups_max = num_htree_groups;
|
||||
ReadHuffmanCodesHelper(color_cache_bits, num_htree_groups,
|
||||
num_htree_groups_max, mapping, dec, &huffman_tables,
|
||||
&htree_groups);
|
||||
(void)ReadHuffmanCodesHelper(color_cache_bits, num_htree_groups,
|
||||
num_htree_groups_max, mapping, dec,
|
||||
&huffman_tables, &htree_groups);
|
||||
|
||||
Error:
|
||||
WebPSafeFree(mapping);
|
||||
|
@ -33,15 +33,15 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
|
||||
if (!mux) return 0;
|
||||
|
||||
WebPData chunk;
|
||||
WebPMuxGetChunk(mux, "EXIF", &chunk);
|
||||
WebPMuxGetChunk(mux, "ICCP", &chunk);
|
||||
WebPMuxGetChunk(mux, "FUZZ", &chunk); // unknown
|
||||
(void)WebPMuxGetChunk(mux, "EXIF", &chunk);
|
||||
(void)WebPMuxGetChunk(mux, "ICCP", &chunk);
|
||||
(void)WebPMuxGetChunk(mux, "FUZZ", &chunk); // unknown
|
||||
|
||||
uint32_t flags;
|
||||
WebPMuxGetFeatures(mux, &flags);
|
||||
(void)WebPMuxGetFeatures(mux, &flags);
|
||||
|
||||
WebPMuxAnimParams params;
|
||||
WebPMuxGetAnimationParams(mux, ¶ms);
|
||||
(void)WebPMuxGetAnimationParams(mux, ¶ms);
|
||||
|
||||
WebPMuxError status;
|
||||
WebPMuxFrameInfo info;
|
||||
@ -72,11 +72,11 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
|
||||
|
||||
WebPChunkIterator chunk_iter;
|
||||
if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
|
||||
WebPDemuxNextChunk(&chunk_iter);
|
||||
(void)WebPDemuxNextChunk(&chunk_iter);
|
||||
}
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) { // 0 == last
|
||||
WebPDemuxPrevChunk(&chunk_iter);
|
||||
(void)WebPDemuxPrevChunk(&chunk_iter);
|
||||
}
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
// Skips FUZZ because the Demux API has no concept of (un)known chunks.
|
||||
|
@ -49,17 +49,17 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
|
||||
if (value % 0x10 == 0) buf_size--;
|
||||
uint8_t* const ext_buf = (uint8_t*)malloc(buf_size);
|
||||
if (value < 0x94) {
|
||||
WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride);
|
||||
(void)WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride);
|
||||
#if !defined(WEBP_REDUCE_CSP)
|
||||
} else if (value < 0xa9) {
|
||||
WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride);
|
||||
(void)WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride);
|
||||
} else if (value < 0xbe) {
|
||||
WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride);
|
||||
(void)WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride);
|
||||
} else if (value < 0xd3) {
|
||||
WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride);
|
||||
(void)WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride);
|
||||
#endif // !defined(WEBP_REDUCE_CSP)
|
||||
} else {
|
||||
WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride);
|
||||
(void)WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride);
|
||||
}
|
||||
free(ext_buf);
|
||||
} else {
|
||||
@ -75,8 +75,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
|
||||
uint8_t* const luma_buf = (uint8_t*)malloc(luma_size);
|
||||
uint8_t* const u_buf = (uint8_t*)malloc(u_size);
|
||||
uint8_t* const v_buf = (uint8_t*)malloc(v_size);
|
||||
WebPDecodeYUVInto(data, size, luma_buf, luma_size, w /* luma_stride */,
|
||||
u_buf, u_size, uv_stride, v_buf, v_size, uv_stride);
|
||||
(void)WebPDecodeYUVInto(data, size, luma_buf, luma_size,
|
||||
w /* luma_stride */, u_buf, u_size, uv_stride,
|
||||
v_buf, v_size, uv_stride);
|
||||
free(luma_buf);
|
||||
free(u_buf);
|
||||
free(v_buf);
|
||||
|
Loading…
Reference in New Issue
Block a user