mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 14:34:33 +02:00
Merge commit 'v0.1.99'
* commit 'v0.1.99': (39 commits) Update ChangeLog add extra precision about default values and behaviour header/doc clean up Makefile.vc: fix webpmux.exe *-dynamic builds remove INAM, ICOP, ... chunks from the test webp file. harmonize authors as "Name (mail@address)" makefile.unix: provide examples/webpmux target update NEWS README: cosmetics man/cwebp.1: wording, change the date add a very crude progress report for lossless rename 'use_argb_input' to 'use_argb' add some padding bytes areas for later use fixing the findings by Frederic Kayser to the bitstream spec add missing ABI compatibility checks Doc: container spec text tweaks add ABI compatibility check mux.h: remove '* const' from function parameters encode.h: remove '* const' from function parameters decode.h: remove '* const' from function parameters ... Conflicts: src/mux/muxinternal.c Change-Id: I635d095c451742e878088464fe6232637a331511
This commit is contained in:
@ -9,9 +9,10 @@ lib_LTLIBRARIES = libwebp.la
|
||||
libwebp_la_SOURCES =
|
||||
libwebpinclude_HEADERS =
|
||||
libwebpinclude_HEADERS += webp/decode.h
|
||||
libwebpinclude_HEADERS += webp/decode_vp8.h
|
||||
libwebpinclude_HEADERS += webp/encode.h
|
||||
libwebpinclude_HEADERS += webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += webp/format_constants.h
|
||||
|
||||
libwebp_la_LIBADD =
|
||||
libwebp_la_LIBADD += dec/libwebpdecode.la
|
||||
@ -19,7 +20,7 @@ libwebp_la_LIBADD += dsp/libwebpdsp.la
|
||||
libwebp_la_LIBADD += enc/libwebpencode.la
|
||||
libwebp_la_LIBADD += utils/libwebputils.la
|
||||
|
||||
libwebp_la_LDFLAGS = -version-info 2:0:0
|
||||
libwebp_la_LDFLAGS = -version-info 3:0:0
|
||||
libwebpincludedir = $(includedir)/webp
|
||||
|
||||
pkgconfig_DATA = libwebp.pc
|
||||
|
@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libwebpdecode.la
|
||||
libwebpdecode_la_SOURCES =
|
||||
libwebpdecode_la_SOURCES += alpha.c
|
||||
libwebpdecode_la_SOURCES += buffer.c
|
||||
libwebpdecode_la_SOURCES += decode_vp8.h
|
||||
libwebpdecode_la_SOURCES += frame.c
|
||||
libwebpdecode_la_SOURCES += idec.c
|
||||
libwebpdecode_la_SOURCES += io.c
|
||||
@ -19,9 +20,9 @@ libwebpdecode_la_SOURCES += webpi.h
|
||||
|
||||
libwebpdecodeinclude_HEADERS =
|
||||
libwebpdecodeinclude_HEADERS += ../webp/decode.h
|
||||
libwebpdecodeinclude_HEADERS += ../webp/decode_vp8.h
|
||||
libwebpdecodeinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS = ../webp/format_constants.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpdecode_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE)
|
||||
libwebpdecodeincludedir = $(includedir)/webp
|
||||
|
@ -166,14 +166,16 @@ VP8StatusCode WebPAllocateDecBuffer(int w, int h,
|
||||
//------------------------------------------------------------------------------
|
||||
// constructors / destructors
|
||||
|
||||
int WebPInitDecBufferInternal(WebPDecBuffer* const buffer, int version) {
|
||||
if (version != WEBP_DECODER_ABI_VERSION) return 0; // version mismatch
|
||||
int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) {
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
|
||||
return 0; // version mismatch
|
||||
}
|
||||
if (buffer == NULL) return 0;
|
||||
memset(buffer, 0, sizeof(*buffer));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WebPFreeDecBuffer(WebPDecBuffer* const buffer) {
|
||||
void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
|
||||
if (buffer != NULL) {
|
||||
if (!buffer->is_external_memory)
|
||||
free(buffer->private_memory);
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef WEBP_WEBP_DECODE_VP8_H_
|
||||
#define WEBP_WEBP_DECODE_VP8_H_
|
||||
|
||||
#include "./decode.h"
|
||||
#include "../webp/decode.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@ -106,22 +106,22 @@ struct VP8Io {
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(int) VP8InitIoInternal(VP8Io* const, int);
|
||||
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.
|
||||
WEBP_EXTERN(int) WebPISetIOHooks(WebPIDecoder* const idec,
|
||||
VP8IoPutHook put,
|
||||
VP8IoSetupHook setup,
|
||||
VP8IoTeardownHook teardown,
|
||||
void* user_data);
|
||||
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;
|
||||
|
||||
// Create a new decoder object.
|
||||
WEBP_EXTERN(VP8Decoder*) VP8New(void);
|
||||
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
|
||||
@ -131,24 +131,24 @@ static WEBP_INLINE int VP8InitIo(VP8Io* const io) {
|
||||
}
|
||||
|
||||
// Start decoding a new picture. Returns true if ok.
|
||||
WEBP_EXTERN(int) VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
|
||||
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.
|
||||
WEBP_EXTERN(int) VP8Decode(VP8Decoder* const dec, VP8Io* const io);
|
||||
int VP8Decode(VP8Decoder* const dec, VP8Io* const io);
|
||||
|
||||
// Return current status of the decoder:
|
||||
WEBP_EXTERN(VP8StatusCode) VP8Status(VP8Decoder* const dec);
|
||||
VP8StatusCode VP8Status(VP8Decoder* const dec);
|
||||
|
||||
// return readable string corresponding to the last status.
|
||||
WEBP_EXTERN(const char*) VP8StatusMessage(VP8Decoder* const dec);
|
||||
const char* VP8StatusMessage(VP8Decoder* const dec);
|
||||
|
||||
// Resets the decoder in its initial state, reclaiming memory.
|
||||
// Not a mandatory call between calls to VP8Decode().
|
||||
WEBP_EXTERN(void) VP8Clear(VP8Decoder* const dec);
|
||||
void VP8Clear(VP8Decoder* const dec);
|
||||
|
||||
// Destroy the decoder object.
|
||||
WEBP_EXTERN(void) VP8Delete(VP8Decoder* const dec);
|
||||
void VP8Delete(VP8Decoder* const dec);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Miscellaneous VP8/VP8L bitstream probing functions.
|
@ -533,7 +533,7 @@ static VP8StatusCode IDecode(WebPIDecoder* idec) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
WebPIDecoder* WebPINewDecoder(WebPDecBuffer* const output_buffer) {
|
||||
WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
|
||||
WebPIDecoder* idec = (WebPIDecoder*)calloc(1, sizeof(WebPIDecoder));
|
||||
if (idec == NULL) {
|
||||
return NULL;
|
||||
@ -554,7 +554,7 @@ WebPIDecoder* WebPINewDecoder(WebPDecBuffer* const output_buffer) {
|
||||
}
|
||||
|
||||
WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* const config) {
|
||||
WebPDecoderConfig* config) {
|
||||
WebPIDecoder* idec;
|
||||
|
||||
// Parse the bitstream's features, if requested:
|
||||
@ -575,7 +575,7 @@ WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
|
||||
return idec;
|
||||
}
|
||||
|
||||
void WebPIDelete(WebPIDecoder* const idec) {
|
||||
void WebPIDelete(WebPIDecoder* idec) {
|
||||
if (idec == NULL) return;
|
||||
if (idec->dec_ != NULL) {
|
||||
if (!idec->is_lossless_) {
|
||||
@ -638,8 +638,8 @@ static VP8StatusCode IDecCheckStatus(const WebPIDecoder* const idec) {
|
||||
return VP8_STATUS_SUSPENDED;
|
||||
}
|
||||
|
||||
VP8StatusCode WebPIAppend(WebPIDecoder* const idec,
|
||||
const uint8_t* const data, size_t data_size) {
|
||||
VP8StatusCode WebPIAppend(WebPIDecoder* idec,
|
||||
const uint8_t* data, size_t data_size) {
|
||||
VP8StatusCode status;
|
||||
if (idec == NULL || data == NULL) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
@ -659,8 +659,8 @@ VP8StatusCode WebPIAppend(WebPIDecoder* const idec,
|
||||
return IDecode(idec);
|
||||
}
|
||||
|
||||
VP8StatusCode WebPIUpdate(WebPIDecoder* const idec,
|
||||
const uint8_t* const data, size_t data_size) {
|
||||
VP8StatusCode WebPIUpdate(WebPIDecoder* idec,
|
||||
const uint8_t* data, size_t data_size) {
|
||||
VP8StatusCode status;
|
||||
if (idec == NULL || data == NULL) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
@ -692,9 +692,9 @@ static const WebPDecBuffer* GetOutputBuffer(const WebPIDecoder* const idec) {
|
||||
return idec->params_.output;
|
||||
}
|
||||
|
||||
const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* const idec,
|
||||
int* const left, int* const top,
|
||||
int* const width, int* const height) {
|
||||
const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec,
|
||||
int* left, int* top,
|
||||
int* width, int* height) {
|
||||
const WebPDecBuffer* const src = GetOutputBuffer(idec);
|
||||
if (left) *left = 0;
|
||||
if (top) *top = 0;
|
||||
@ -709,7 +709,7 @@ const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* const idec,
|
||||
return src;
|
||||
}
|
||||
|
||||
uint8_t* WebPIDecGetRGB(const WebPIDecoder* const idec, int* last_y,
|
||||
uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
|
||||
int* width, int* height, int* stride) {
|
||||
const WebPDecBuffer* const src = GetOutputBuffer(idec);
|
||||
if (!src) return NULL;
|
||||
@ -725,7 +725,7 @@ uint8_t* WebPIDecGetRGB(const WebPIDecoder* const idec, int* last_y,
|
||||
return src->u.RGBA.rgba;
|
||||
}
|
||||
|
||||
uint8_t* WebPIDecGetYUV(const WebPIDecoder* const idec, int* last_y,
|
||||
uint8_t* WebPIDecGetYUV(const WebPIDecoder* idec, int* last_y,
|
||||
uint8_t** u, uint8_t** v,
|
||||
int* width, int* height, int *stride, int* uv_stride) {
|
||||
const WebPDecBuffer* const src = GetOutputBuffer(idec);
|
||||
|
@ -35,9 +35,10 @@ static void SetOk(VP8Decoder* const dec) {
|
||||
}
|
||||
|
||||
int VP8InitIoInternal(VP8Io* const io, int version) {
|
||||
if (version != WEBP_DECODER_ABI_VERSION)
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
|
||||
return 0; // mismatch error
|
||||
if (io) {
|
||||
}
|
||||
if (io != NULL) {
|
||||
memset(io, 0, sizeof(*io));
|
||||
}
|
||||
return 1;
|
||||
@ -45,7 +46,7 @@ int VP8InitIoInternal(VP8Io* const io, int version) {
|
||||
|
||||
VP8Decoder* VP8New(void) {
|
||||
VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(VP8Decoder));
|
||||
if (dec) {
|
||||
if (dec != NULL) {
|
||||
SetOk(dec);
|
||||
WebPWorkerInit(&dec->worker_);
|
||||
dec->ready_ = 0;
|
||||
@ -60,13 +61,13 @@ VP8StatusCode VP8Status(VP8Decoder* const dec) {
|
||||
}
|
||||
|
||||
const char* VP8StatusMessage(VP8Decoder* const dec) {
|
||||
if (!dec) return "no object";
|
||||
if (dec == NULL) return "no object";
|
||||
if (!dec->error_msg_) return "OK";
|
||||
return dec->error_msg_;
|
||||
}
|
||||
|
||||
void VP8Delete(VP8Decoder* const dec) {
|
||||
if (dec) {
|
||||
if (dec != NULL) {
|
||||
VP8Clear(dec);
|
||||
free(dec);
|
||||
}
|
||||
@ -136,7 +137,7 @@ int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
|
||||
// Header parsing
|
||||
|
||||
static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
|
||||
assert(hdr);
|
||||
assert(hdr != NULL);
|
||||
hdr->use_segment_ = 0;
|
||||
hdr->update_map_ = 0;
|
||||
hdr->absolute_delta_ = 1;
|
||||
@ -147,8 +148,8 @@ static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
|
||||
// Paragraph 9.3
|
||||
static int ParseSegmentHeader(VP8BitReader* br,
|
||||
VP8SegmentHeader* hdr, VP8Proba* proba) {
|
||||
assert(br);
|
||||
assert(hdr);
|
||||
assert(br != NULL);
|
||||
assert(hdr != NULL);
|
||||
hdr->use_segment_ = VP8Get(br);
|
||||
if (hdr->use_segment_) {
|
||||
hdr->update_map_ = VP8Get(br);
|
||||
|
@ -28,7 +28,7 @@ extern "C" {
|
||||
// version numbers
|
||||
#define DEC_MAJ_VERSION 0
|
||||
#define DEC_MIN_VERSION 1
|
||||
#define DEC_REV_VERSION 3
|
||||
#define DEC_REV_VERSION 99
|
||||
|
||||
#define ONLY_KEYFRAME_CODE // to remove any code related to P-Frames
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
//
|
||||
// main entry for the decoder
|
||||
//
|
||||
// Author: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// jyrki@google.com (Jyrki Alakuijala)
|
||||
// Authors: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// Jyrki Alakuijala (jyrki@google.com)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -565,13 +565,14 @@ static int DecodeImageData(VP8LDecoder* const dec,
|
||||
int col = 0, row = 0;
|
||||
VP8LBitReader* const br = &dec->br_;
|
||||
VP8LMetadata* const hdr = &dec->hdr_;
|
||||
VP8LColorCache* const color_cache = hdr->color_cache_;
|
||||
HTreeGroup* htree_group = hdr->htree_groups_;
|
||||
uint32_t* src = data;
|
||||
uint32_t* last_cached = data;
|
||||
uint32_t* const src_end = data + width * height;
|
||||
const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
|
||||
const int color_cache_limit = len_code_limit + hdr->color_cache_size_;
|
||||
VP8LColorCache* const color_cache =
|
||||
(hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
|
||||
const int mask = hdr->huffman_mask_;
|
||||
|
||||
assert(htree_group != NULL);
|
||||
@ -784,7 +785,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
|
||||
|
||||
free(hdr->huffman_image_);
|
||||
DeleteHtreeGroups(hdr->htree_groups_, hdr->num_htree_groups_);
|
||||
VP8LColorCacheDelete(hdr->color_cache_);
|
||||
VP8LColorCacheClear(&hdr->color_cache_);
|
||||
InitMetadata(hdr);
|
||||
}
|
||||
|
||||
@ -875,13 +876,13 @@ static int DecodeImageStream(int xsize, int ysize,
|
||||
// Finish setting up the color-cache
|
||||
if (color_cache_bits > 0) {
|
||||
hdr->color_cache_size_ = 1 << color_cache_bits;
|
||||
hdr->color_cache_ = (VP8LColorCache*)malloc(sizeof(*hdr->color_cache_));
|
||||
if (hdr->color_cache_ == NULL ||
|
||||
!VP8LColorCacheInit(hdr->color_cache_, color_cache_bits)) {
|
||||
if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
ok = 0;
|
||||
goto End;
|
||||
}
|
||||
} else {
|
||||
hdr->color_cache_size_ = 0;
|
||||
}
|
||||
UpdateDecoder(dec, transform_xsize, transform_ysize);
|
||||
|
||||
@ -890,11 +891,21 @@ static int DecodeImageStream(int xsize, int ysize,
|
||||
goto End;
|
||||
}
|
||||
|
||||
data = (uint32_t*)malloc(transform_xsize * transform_ysize * sizeof(*data));
|
||||
if (data == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
ok = 0;
|
||||
goto End;
|
||||
{
|
||||
const uint64_t total_size =
|
||||
transform_xsize * transform_ysize * sizeof(*data);
|
||||
if (total_size != (size_t)total_size) {
|
||||
// This shouldn't happen, because of transform_bits limit, but...
|
||||
dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||
ok = 0;
|
||||
goto End;
|
||||
}
|
||||
data = (uint32_t*)malloc((size_t)total_size);
|
||||
if (data == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
ok = 0;
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
|
||||
// Use the Huffman trees to decode the LZ77 encoded data.
|
||||
|
@ -45,7 +45,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int color_cache_size_;
|
||||
VP8LColorCache *color_cache_;
|
||||
VP8LColorCache color_cache_;
|
||||
|
||||
int huffman_mask_;
|
||||
int huffman_subsample_bits_;
|
||||
|
@ -649,9 +649,9 @@ int WebPGetInfo(const uint8_t* data, size_t data_size,
|
||||
//------------------------------------------------------------------------------
|
||||
// Advance decoding API
|
||||
|
||||
int WebPInitDecoderConfigInternal(WebPDecoderConfig* const config,
|
||||
int WebPInitDecoderConfigInternal(WebPDecoderConfig* config,
|
||||
int version) {
|
||||
if (version != WEBP_DECODER_ABI_VERSION) {
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
|
||||
return 0; // version mismatch
|
||||
}
|
||||
if (config == NULL) {
|
||||
@ -664,10 +664,10 @@ int WebPInitDecoderConfigInternal(WebPDecoderConfig* const config,
|
||||
}
|
||||
|
||||
VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
|
||||
WebPBitstreamFeatures* const features,
|
||||
WebPBitstreamFeatures* features,
|
||||
int version) {
|
||||
VP8StatusCode status;
|
||||
if (version != WEBP_DECODER_ABI_VERSION) {
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
|
||||
return VP8_STATUS_INVALID_PARAM; // version mismatch
|
||||
}
|
||||
if (features == NULL) {
|
||||
@ -682,7 +682,7 @@ VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
|
||||
}
|
||||
|
||||
VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* const config) {
|
||||
WebPDecoderConfig* config) {
|
||||
WebPDecParams params;
|
||||
VP8StatusCode status;
|
||||
|
||||
|
@ -17,7 +17,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../utils/rescaler.h"
|
||||
#include "../webp/decode_vp8.h"
|
||||
#include "./decode_vp8.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecParams: Decoding output parameters. Transient internal object.
|
||||
|
@ -18,8 +18,8 @@ libwebpdsp_la_SOURCES += yuv.h
|
||||
|
||||
libwebpdspinclude_HEADERS = ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../dec/decode_vp8.h
|
||||
noinst_HEADERS += ../webp/decode.h
|
||||
noinst_HEADERS += ../webp/decode_vp8.h
|
||||
|
||||
libwebpdsp_la_LDFLAGS = -lm
|
||||
libwebpdsp_la_CPPFLAGS = $(USE_EXPERIMENTAL_CODE)
|
||||
|
@ -8,7 +8,7 @@
|
||||
// Image transforms and color space conversion methods for lossless decoder.
|
||||
//
|
||||
// Authors: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// jyrki@google.com (Jyrki Alakuijala)
|
||||
// Jyrki Alakuijala (jyrki@google.com)
|
||||
// Urvang Joshi (urvang@google.com)
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -7,8 +7,8 @@
|
||||
//
|
||||
// Image transforms and color space conversion methods for lossless decoder.
|
||||
//
|
||||
// Author: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// jyrki@google.com (Jyrki Alakuijala)
|
||||
// Authors: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// Jyrki Alakuijala (jyrki@google.com)
|
||||
|
||||
#ifndef WEBP_DSP_LOSSLESS_H_
|
||||
#define WEBP_DSP_LOSSLESS_H_
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef WEBP_DSP_YUV_H_
|
||||
#define WEBP_DSP_YUV_H_
|
||||
|
||||
#include "../webp/decode_vp8.h"
|
||||
#include "../dec/decode_vp8.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
@ -62,7 +62,7 @@ static int EncodeLossless(const uint8_t* data, int width, int height,
|
||||
WebPPictureInit(&picture);
|
||||
picture.width = width;
|
||||
picture.height = height;
|
||||
picture.use_argb_input = 1;
|
||||
picture.use_argb = 1;
|
||||
if (!WebPPictureAlloc(&picture)) return 0;
|
||||
|
||||
// Transfer the alpha values to the green channel.
|
||||
|
@ -146,18 +146,20 @@ static int HashChainFindCopy(const HashChain* const p,
|
||||
const uint64_t hash_code = GetPixPairHash64(&argb[index]);
|
||||
int prev_length = 0;
|
||||
int64_t best_val = 0;
|
||||
int best_length = 0;
|
||||
int best_distance = 0;
|
||||
const uint32_t* const argb_start = argb + index;
|
||||
const int iter_min_mult = (quality < 50) ? 2 : (quality < 75) ? 4 : 8;
|
||||
const int iter_min = -quality * iter_min_mult;
|
||||
int iter_cnt = 10 + (quality >> 1);
|
||||
const int min_pos = (index > WINDOW_SIZE) ? index - WINDOW_SIZE : 0;
|
||||
int32_t pos;
|
||||
int64_t val;
|
||||
int best_length = 0;
|
||||
int best_distance = 0;
|
||||
int pos;
|
||||
|
||||
assert(xsize > 0);
|
||||
for (pos = p->hash_to_first_index_[hash_code];
|
||||
pos >= min_pos;
|
||||
pos = p->chain_[pos]) {
|
||||
int64_t val;
|
||||
int curr_length;
|
||||
if (iter_cnt < 0) {
|
||||
if (iter_cnt < iter_min || best_val >= 0xff0000) {
|
||||
@ -166,10 +168,10 @@ static int HashChainFindCopy(const HashChain* const p,
|
||||
}
|
||||
--iter_cnt;
|
||||
if (best_length != 0 &&
|
||||
argb[pos + best_length - 1] != argb[index + best_length - 1]) {
|
||||
argb[pos + best_length - 1] != argb_start[best_length - 1]) {
|
||||
continue;
|
||||
}
|
||||
curr_length = FindMatchLength(argb + pos, argb + index, maxlen);
|
||||
curr_length = FindMatchLength(argb + pos, argb_start, maxlen);
|
||||
if (curr_length < prev_length) {
|
||||
continue;
|
||||
}
|
||||
|
@ -19,9 +19,9 @@ extern "C" {
|
||||
// WebPConfig
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int WebPConfigInitInternal(WebPConfig* const config,
|
||||
int WebPConfigInitInternal(WebPConfig* config,
|
||||
WebPPreset preset, float quality, int version) {
|
||||
if (version != WEBP_ENCODER_ABI_VERSION) {
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) {
|
||||
return 0; // caller/system version mismatch!
|
||||
}
|
||||
if (config == NULL) return 0;
|
||||
@ -80,7 +80,7 @@ int WebPConfigInitInternal(WebPConfig* const config,
|
||||
return WebPValidateConfig(config);
|
||||
}
|
||||
|
||||
int WebPValidateConfig(const WebPConfig* const config) {
|
||||
int WebPValidateConfig(const WebPConfig* config) {
|
||||
if (config == NULL) return 0;
|
||||
if (config->quality < 0 || config->quality > 100)
|
||||
return 0;
|
||||
|
@ -88,8 +88,7 @@ VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void VP8LConvertPopulationCountTableToBitEstimates(
|
||||
int num_symbols, const int* const population_counts,
|
||||
double* const output) {
|
||||
int num_symbols, const int population_counts[], double output[]) {
|
||||
int sum = 0;
|
||||
int nonzeros = 0;
|
||||
int i;
|
||||
@ -206,9 +205,6 @@ double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
double VP8LHistogramEstimateBits(const VP8LHistogram* const p) {
|
||||
return VP8LHistogramEstimateBitsHeader(p) + VP8LHistogramEstimateBitsBulk(p);
|
||||
}
|
||||
|
||||
// Returns the cost encode the rle-encoded entropy code.
|
||||
// The constants in this function are experimental.
|
||||
@ -249,7 +245,8 @@ static double HuffmanCost(const int* const population, int length) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
double VP8LHistogramEstimateBitsHeader(const VP8LHistogram* const p) {
|
||||
// Estimates the Huffman dictionary + other block overhead size.
|
||||
static double HistogramEstimateBitsHeader(const VP8LHistogram* const p) {
|
||||
return HuffmanCost(&p->alpha_[0], 256) +
|
||||
HuffmanCost(&p->red_[0], 256) +
|
||||
HuffmanCost(&p->literal_[0], VP8LHistogramNumCodes(p)) +
|
||||
@ -257,6 +254,10 @@ double VP8LHistogramEstimateBitsHeader(const VP8LHistogram* const p) {
|
||||
HuffmanCost(&p->distance_[0], NUM_DISTANCE_CODES);
|
||||
}
|
||||
|
||||
double VP8LHistogramEstimateBits(const VP8LHistogram* const p) {
|
||||
return HistogramEstimateBitsHeader(p) + VP8LHistogramEstimateBitsBulk(p);
|
||||
}
|
||||
|
||||
static void HistogramBuildImage(int xsize, int histo_bits,
|
||||
const VP8LBackwardRefs* const backward_refs,
|
||||
VP8LHistogramSet* const image) {
|
||||
|
@ -76,10 +76,6 @@ void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
|
||||
// approximately maps to.
|
||||
double VP8LHistogramEstimateBits(const VP8LHistogram* const p);
|
||||
|
||||
// This function estimates the Huffman dictionary + other block overhead
|
||||
// size for creating a new deflate block.
|
||||
double VP8LHistogramEstimateBitsHeader(const VP8LHistogram* const p);
|
||||
|
||||
// This function estimates the cost in bits excluding the bits needed to
|
||||
// represent the entropy code itself.
|
||||
double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p);
|
||||
@ -100,34 +96,13 @@ static WEBP_INLINE void VP8LHistogramAdd(VP8LHistogram* const p,
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE void VP8LHistogramRemove(VP8LHistogram* const p,
|
||||
const VP8LHistogram* const a) {
|
||||
int i;
|
||||
for (i = 0; i < PIX_OR_COPY_CODES_MAX; ++i) {
|
||||
p->literal_[i] -= a->literal_[i];
|
||||
assert(p->literal_[i] >= 0);
|
||||
}
|
||||
for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
|
||||
p->distance_[i] -= a->distance_[i];
|
||||
assert(p->distance_[i] >= 0);
|
||||
}
|
||||
for (i = 0; i < 256; ++i) {
|
||||
p->red_[i] -= a->red_[i];
|
||||
p->blue_[i] -= a->blue_[i];
|
||||
p->alpha_[i] -= a->alpha_[i];
|
||||
assert(p->red_[i] >= 0);
|
||||
assert(p->blue_[i] >= 0);
|
||||
assert(p->alpha_[i] >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE int VP8LHistogramNumCodes(const VP8LHistogram* const p) {
|
||||
return 256 + NUM_LENGTH_CODES +
|
||||
((p->palette_code_bits_ > 0) ? (1 << p->palette_code_bits_) : 0);
|
||||
}
|
||||
|
||||
void VP8LConvertPopulationCountTableToBitEstimates(
|
||||
int n, const int* const population_counts, double* const output);
|
||||
int num_symbols, const int population_counts[], double output[]);
|
||||
|
||||
// Builds the histogram image.
|
||||
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||
|
@ -34,14 +34,14 @@ static const union {
|
||||
// WebPPicture
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int WebPPictureAlloc(WebPPicture* const picture) {
|
||||
int WebPPictureAlloc(WebPPicture* picture) {
|
||||
if (picture != NULL) {
|
||||
const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK;
|
||||
const int has_alpha = picture->colorspace & WEBP_CSP_ALPHA_BIT;
|
||||
const int width = picture->width;
|
||||
const int height = picture->height;
|
||||
|
||||
if (!picture->use_argb_input) {
|
||||
if (!picture->use_argb) {
|
||||
const int y_stride = width;
|
||||
const int uv_width = HALVE(width);
|
||||
const int uv_height = HALVE(height);
|
||||
@ -172,7 +172,7 @@ static int PictureAllocARGB(WebPPicture* const picture) {
|
||||
WebPPicture tmp;
|
||||
free(picture->memory_argb_);
|
||||
PictureResetARGB(picture);
|
||||
picture->use_argb_input = 1;
|
||||
picture->use_argb = 1;
|
||||
WebPPictureGrabSpecs(picture, &tmp);
|
||||
if (!WebPPictureAlloc(&tmp)) {
|
||||
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||
@ -184,7 +184,7 @@ static int PictureAllocARGB(WebPPicture* const picture) {
|
||||
}
|
||||
|
||||
// Release memory owned by 'picture' (both YUV and ARGB buffers).
|
||||
void WebPPictureFree(WebPPicture* const picture) {
|
||||
void WebPPictureFree(WebPPicture* picture) {
|
||||
if (picture != NULL) {
|
||||
free(picture->memory_);
|
||||
free(picture->memory_argb_);
|
||||
@ -209,7 +209,7 @@ static void CopyPlane(const uint8_t* src, int src_stride,
|
||||
// Adjust top-left corner to chroma sample position.
|
||||
static void SnapTopLeftPosition(const WebPPicture* const pic,
|
||||
int* const left, int* const top) {
|
||||
if (!pic->use_argb_input) {
|
||||
if (!pic->use_argb) {
|
||||
const int is_yuv422 = IS_YUV_CSP(pic->colorspace, WEBP_YUV422);
|
||||
if (IS_YUV_CSP(pic->colorspace, WEBP_YUV420) || is_yuv422) {
|
||||
*left &= ~1;
|
||||
@ -230,14 +230,14 @@ static int AdjustAndCheckRectangle(const WebPPicture* const pic,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPPictureCopy(const WebPPicture* const src, WebPPicture* const dst) {
|
||||
int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
|
||||
if (src == NULL || dst == NULL) return 0;
|
||||
if (src == dst) return 1;
|
||||
|
||||
WebPPictureGrabSpecs(src, dst);
|
||||
if (!WebPPictureAlloc(dst)) return 0;
|
||||
|
||||
if (!src->use_argb_input) {
|
||||
if (!src->use_argb) {
|
||||
CopyPlane(src->y, src->y_stride,
|
||||
dst->y, dst->y_stride, dst->width, dst->height);
|
||||
CopyPlane(src->u, src->uv_stride,
|
||||
@ -268,17 +268,17 @@ int WebPPictureCopy(const WebPPicture* const src, WebPPicture* const dst) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPPictureIsView(const WebPPicture* const picture) {
|
||||
int WebPPictureIsView(const WebPPicture* picture) {
|
||||
if (picture == NULL) return 0;
|
||||
if (picture->use_argb_input) {
|
||||
if (picture->use_argb) {
|
||||
return (picture->memory_argb_ == NULL);
|
||||
}
|
||||
return (picture->memory_ == NULL);
|
||||
}
|
||||
|
||||
int WebPPictureView(const WebPPicture* const src,
|
||||
int WebPPictureView(const WebPPicture* src,
|
||||
int left, int top, int width, int height,
|
||||
WebPPicture* const dst) {
|
||||
WebPPicture* dst) {
|
||||
if (src == NULL || dst == NULL) return 0;
|
||||
|
||||
// verify rectangle position.
|
||||
@ -289,7 +289,7 @@ int WebPPictureView(const WebPPicture* const src,
|
||||
}
|
||||
dst->width = width;
|
||||
dst->height = height;
|
||||
if (!src->use_argb_input) {
|
||||
if (!src->use_argb) {
|
||||
dst->y = src->y + top * src->y_stride + left;
|
||||
dst->u = src->u + (top >> 1) * src->uv_stride + (left >> 1);
|
||||
dst->v = src->v + (top >> 1) * src->uv_stride + (left >> 1);
|
||||
@ -313,7 +313,7 @@ int WebPPictureView(const WebPPicture* const src,
|
||||
//------------------------------------------------------------------------------
|
||||
// Picture cropping
|
||||
|
||||
int WebPPictureCrop(WebPPicture* const pic,
|
||||
int WebPPictureCrop(WebPPicture* pic,
|
||||
int left, int top, int width, int height) {
|
||||
WebPPicture tmp;
|
||||
|
||||
@ -325,7 +325,7 @@ int WebPPictureCrop(WebPPicture* const pic,
|
||||
tmp.height = height;
|
||||
if (!WebPPictureAlloc(&tmp)) return 0;
|
||||
|
||||
if (!pic->use_argb_input) {
|
||||
if (!pic->use_argb) {
|
||||
const int y_offset = top * pic->y_stride + left;
|
||||
const int uv_offset = (top / 2) * pic->uv_stride + left / 2;
|
||||
CopyPlane(pic->y + y_offset, pic->y_stride,
|
||||
@ -391,7 +391,7 @@ static void RescalePlane(const uint8_t* src,
|
||||
}
|
||||
}
|
||||
|
||||
int WebPPictureRescale(WebPPicture* const pic, int width, int height) {
|
||||
int WebPPictureRescale(WebPPicture* pic, int width, int height) {
|
||||
WebPPicture tmp;
|
||||
int prev_width, prev_height;
|
||||
int32_t* work;
|
||||
@ -415,7 +415,7 @@ int WebPPictureRescale(WebPPicture* const pic, int width, int height) {
|
||||
tmp.height = height;
|
||||
if (!WebPPictureAlloc(&tmp)) return 0;
|
||||
|
||||
if (!pic->use_argb_input) {
|
||||
if (!pic->use_argb) {
|
||||
work = (int32_t*)malloc(2 * width * sizeof(*work));
|
||||
if (work == NULL) {
|
||||
WebPPictureFree(&tmp);
|
||||
@ -471,14 +471,14 @@ int WebPPictureRescale(WebPPicture* const pic, int width, int height) {
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPMemoryWriter: Write-to-memory
|
||||
|
||||
void WebPMemoryWriterInit(WebPMemoryWriter* const writer) {
|
||||
void WebPMemoryWriterInit(WebPMemoryWriter* writer) {
|
||||
writer->mem = NULL;
|
||||
writer->size = 0;
|
||||
writer->max_size = 0;
|
||||
}
|
||||
|
||||
int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* const picture) {
|
||||
const WebPPicture* picture) {
|
||||
WebPMemoryWriter* const w = (WebPMemoryWriter*)picture->custom_ptr;
|
||||
size_t next_size;
|
||||
if (w == NULL) {
|
||||
@ -526,9 +526,9 @@ static int CheckNonOpaque(const uint8_t* alpha, int width, int height,
|
||||
}
|
||||
|
||||
// Checking for the presence of non-opaque alpha.
|
||||
int WebPPictureHasTransparency(const WebPPicture* const picture) {
|
||||
int WebPPictureHasTransparency(const WebPPicture* picture) {
|
||||
if (picture == NULL) return 0;
|
||||
if (!picture->use_argb_input) {
|
||||
if (!picture->use_argb) {
|
||||
return CheckNonOpaque(picture->a, picture->width, picture->height,
|
||||
1, picture->a_stride);
|
||||
} else {
|
||||
@ -625,7 +625,7 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
|
||||
const int has_alpha = CheckNonOpaque(a_ptr, width, height, step, rgb_stride);
|
||||
|
||||
picture->colorspace = uv_csp;
|
||||
picture->use_argb_input = 0;
|
||||
picture->use_argb = 0;
|
||||
if (has_alpha) {
|
||||
picture->colorspace |= WEBP_CSP_ALPHA_BIT;
|
||||
}
|
||||
@ -704,7 +704,7 @@ static int Import(WebPPicture* const picture,
|
||||
const int width = picture->width;
|
||||
const int height = picture->height;
|
||||
|
||||
if (!picture->use_argb_input) {
|
||||
if (!picture->use_argb) {
|
||||
return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride,
|
||||
picture);
|
||||
}
|
||||
@ -750,40 +750,40 @@ static int Import(WebPPicture* const picture,
|
||||
#undef SUM1
|
||||
#undef RGB_TO_UV
|
||||
|
||||
int WebPPictureImportRGB(WebPPicture* const picture,
|
||||
const uint8_t* const rgb, int rgb_stride) {
|
||||
int WebPPictureImportRGB(WebPPicture* picture,
|
||||
const uint8_t* rgb, int rgb_stride) {
|
||||
return Import(picture, rgb, rgb_stride, 3, 0, 0);
|
||||
}
|
||||
|
||||
int WebPPictureImportBGR(WebPPicture* const picture,
|
||||
const uint8_t* const rgb, int rgb_stride) {
|
||||
int WebPPictureImportBGR(WebPPicture* picture,
|
||||
const uint8_t* rgb, int rgb_stride) {
|
||||
return Import(picture, rgb, rgb_stride, 3, 1, 0);
|
||||
}
|
||||
|
||||
int WebPPictureImportRGBA(WebPPicture* const picture,
|
||||
const uint8_t* const rgba, int rgba_stride) {
|
||||
int WebPPictureImportRGBA(WebPPicture* picture,
|
||||
const uint8_t* rgba, int rgba_stride) {
|
||||
return Import(picture, rgba, rgba_stride, 4, 0, 1);
|
||||
}
|
||||
|
||||
int WebPPictureImportBGRA(WebPPicture* const picture,
|
||||
const uint8_t* const rgba, int rgba_stride) {
|
||||
int WebPPictureImportBGRA(WebPPicture* picture,
|
||||
const uint8_t* rgba, int rgba_stride) {
|
||||
return Import(picture, rgba, rgba_stride, 4, 1, 1);
|
||||
}
|
||||
|
||||
int WebPPictureImportRGBX(WebPPicture* const picture,
|
||||
const uint8_t* const rgba, int rgba_stride) {
|
||||
int WebPPictureImportRGBX(WebPPicture* picture,
|
||||
const uint8_t* rgba, int rgba_stride) {
|
||||
return Import(picture, rgba, rgba_stride, 4, 0, 0);
|
||||
}
|
||||
|
||||
int WebPPictureImportBGRX(WebPPicture* const picture,
|
||||
const uint8_t* const rgba, int rgba_stride) {
|
||||
int WebPPictureImportBGRX(WebPPicture* picture,
|
||||
const uint8_t* rgba, int rgba_stride) {
|
||||
return Import(picture, rgba, rgba_stride, 4, 1, 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Automatic YUV <-> ARGB conversions.
|
||||
|
||||
int WebPPictureYUVAToARGB(WebPPicture* const picture) {
|
||||
int WebPPictureYUVAToARGB(WebPPicture* picture) {
|
||||
if (picture == NULL) return 0;
|
||||
if (picture->memory_ == NULL || picture->y == NULL ||
|
||||
picture->u == NULL || picture->v == NULL) {
|
||||
@ -842,7 +842,7 @@ int WebPPictureYUVAToARGB(WebPPicture* const picture) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPPictureARGBToYUVA(WebPPicture* const picture, WebPEncCSP colorspace) {
|
||||
int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace) {
|
||||
if (picture == NULL) return 0;
|
||||
if (picture->argb == NULL) {
|
||||
return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
|
||||
@ -856,7 +856,7 @@ int WebPPictureARGBToYUVA(WebPPicture* const picture, WebPEncCSP colorspace) {
|
||||
// would be calling WebPPictureFree(picture) otherwise.
|
||||
WebPPicture tmp = *picture;
|
||||
PictureResetARGB(&tmp); // reset ARGB buffer so that it's not free()'d.
|
||||
tmp.use_argb_input = 0;
|
||||
tmp.use_argb = 0;
|
||||
tmp.colorspace = colorspace & WEBP_CSP_UV_MASK;
|
||||
if (!ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, &tmp)) {
|
||||
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||
@ -896,7 +896,7 @@ static WEBP_INLINE void flatten(uint8_t* ptr, int v, int stride, int size) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebPCleanupTransparentArea(WebPPicture* const pic) {
|
||||
void WebPCleanupTransparentArea(WebPPicture* pic) {
|
||||
int x, y, w, h;
|
||||
const uint8_t* a_ptr;
|
||||
int values[3] = { 0 };
|
||||
@ -942,8 +942,7 @@ void WebPCleanupTransparentArea(WebPPicture* const pic) {
|
||||
// Max value returned in case of exact similarity.
|
||||
static const double kMinDistortion_dB = 99.;
|
||||
|
||||
int WebPPictureDistortion(const WebPPicture* const pic1,
|
||||
const WebPPicture* const pic2,
|
||||
int WebPPictureDistortion(const WebPPicture* pic1, const WebPPicture* pic2,
|
||||
int type, float result[5]) {
|
||||
int c;
|
||||
DistoStats stats[5];
|
||||
@ -958,8 +957,7 @@ int WebPPictureDistortion(const WebPPicture* const pic1,
|
||||
return 0;
|
||||
}
|
||||
// TODO(skal): provide distortion for ARGB too.
|
||||
if (pic1->use_argb_input == 1 ||
|
||||
pic1->use_argb_input != pic2->use_argb_input) {
|
||||
if (pic1->use_argb == 1 || pic1->use_argb != pic2->use_argb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1008,7 +1006,8 @@ int WebPPictureDistortion(const WebPPicture* const pic1,
|
||||
typedef int (*Importer)(WebPPicture* const, const uint8_t* const, int);
|
||||
|
||||
static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
|
||||
Importer import, float quality_factor, uint8_t** output) {
|
||||
Importer import, float quality_factor, int lossless,
|
||||
uint8_t** output) {
|
||||
WebPPicture pic;
|
||||
WebPConfig config;
|
||||
WebPMemoryWriter wrt;
|
||||
@ -1019,6 +1018,8 @@ static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
|
||||
return 0; // shouldn't happen, except if system installation is broken
|
||||
}
|
||||
|
||||
config.lossless = !!lossless;
|
||||
pic.use_argb = !!lossless;
|
||||
pic.width = width;
|
||||
pic.height = height;
|
||||
pic.writer = WebPMemoryWrite;
|
||||
@ -1036,10 +1037,10 @@ static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
|
||||
return wrt.size;
|
||||
}
|
||||
|
||||
#define ENCODE_FUNC(NAME, IMPORTER) \
|
||||
size_t NAME(const uint8_t* in, int w, int h, int bps, float q, \
|
||||
uint8_t** out) { \
|
||||
return Encode(in, w, h, bps, IMPORTER, q, out); \
|
||||
#define ENCODE_FUNC(NAME, IMPORTER) \
|
||||
size_t NAME(const uint8_t* in, int w, int h, int bps, float q, \
|
||||
uint8_t** out) { \
|
||||
return Encode(in, w, h, bps, IMPORTER, q, 0, out); \
|
||||
}
|
||||
|
||||
ENCODE_FUNC(WebPEncodeRGB, WebPPictureImportRGB);
|
||||
@ -1049,6 +1050,19 @@ ENCODE_FUNC(WebPEncodeBGRA, WebPPictureImportBGRA);
|
||||
|
||||
#undef ENCODE_FUNC
|
||||
|
||||
#define LOSSLESS_DEFAULT_QUALITY 70.
|
||||
#define LOSSLESS_ENCODE_FUNC(NAME, IMPORTER) \
|
||||
size_t NAME(const uint8_t* in, int w, int h, int bps, uint8_t** out) { \
|
||||
return Encode(in, w, h, bps, IMPORTER, LOSSLESS_DEFAULT_QUALITY, 1, out); \
|
||||
}
|
||||
|
||||
LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGB, WebPPictureImportRGB);
|
||||
LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGR, WebPPictureImportBGR);
|
||||
LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGBA, WebPPictureImportRGBA);
|
||||
LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGRA, WebPPictureImportBGRA);
|
||||
|
||||
#undef LOSSLESS_ENCODE_FUNC
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -27,7 +27,7 @@ extern "C" {
|
||||
// version numbers
|
||||
#define ENC_MAJ_VERSION 0
|
||||
#define ENC_MIN_VERSION 1
|
||||
#define ENC_REV_VERSION 3
|
||||
#define ENC_REV_VERSION 99
|
||||
|
||||
// size of histogram used by CollectHistogram.
|
||||
#define MAX_COEFF_THRESH 64
|
||||
|
@ -28,8 +28,6 @@ extern "C" {
|
||||
|
||||
#define PALETTE_KEY_RIGHT_SHIFT 22 // Key for 1K buffer.
|
||||
#define MAX_HUFF_IMAGE_SIZE (16 * 1024 * 1024)
|
||||
#define MIN_HISTO_BITS 2
|
||||
#define MAX_HISTO_BITS 9
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Palette
|
||||
@ -517,7 +515,8 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||
VP8LBackwardRefs refs;
|
||||
uint16_t* const histogram_symbols =
|
||||
(uint16_t*)malloc(histogram_image_xysize * sizeof(*histogram_symbols));
|
||||
assert(histogram_bits >= MIN_HISTO_BITS && histogram_bits <= MAX_HISTO_BITS);
|
||||
assert(histogram_bits >= MIN_HUFFMAN_BITS);
|
||||
assert(histogram_bits <= MAX_HUFFMAN_BITS);
|
||||
if (histogram_image == NULL || histogram_symbols == NULL) goto Error;
|
||||
|
||||
// Calculate backward references from ARGB image.
|
||||
@ -894,8 +893,8 @@ static int GetHistoBits(const WebPConfig* const config,
|
||||
if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
|
||||
++histo_bits;
|
||||
}
|
||||
return (histo_bits < MIN_HISTO_BITS) ? MIN_HISTO_BITS :
|
||||
(histo_bits > MAX_HISTO_BITS) ? MAX_HISTO_BITS : histo_bits;
|
||||
return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS :
|
||||
(histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits;
|
||||
}
|
||||
|
||||
static void InitEncParams(VP8LEncoder* const enc) {
|
||||
@ -1028,6 +1027,7 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
||||
int width, height;
|
||||
int has_alpha;
|
||||
size_t coded_size;
|
||||
int percent = 0;
|
||||
WebPEncodingError err = VP8_ENC_OK;
|
||||
VP8LBitWriter bw;
|
||||
|
||||
@ -1040,6 +1040,11 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
||||
|
||||
width = picture->width;
|
||||
height = picture->height;
|
||||
if (!WebPReportProgress(picture, 1, &percent)) {
|
||||
UserAbort:
|
||||
err = VP8_ENC_ERROR_USER_ABORT;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Write image size.
|
||||
VP8LBitWriterInit(&bw, (width * height) >> 1);
|
||||
@ -1055,14 +1060,21 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
|
||||
|
||||
// Encode main image stream.
|
||||
err = VP8LEncodeStream(config, picture, &bw);
|
||||
if (err != VP8_ENC_OK) goto Error;
|
||||
|
||||
// TODO(skal): have a fine-grained progress report in VP8LEncodeStream().
|
||||
if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
|
||||
|
||||
// Finish the RIFF chunk.
|
||||
err = WriteImage(picture, &bw, &coded_size);
|
||||
if (err != VP8_ENC_OK) goto Error;
|
||||
|
||||
if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
|
||||
|
||||
// Collect some stats if needed.
|
||||
if (picture->stats != NULL) {
|
||||
WebPAuxStats* const stats = picture->stats;
|
||||
|
@ -46,8 +46,8 @@ static int DummyWriter(const uint8_t* data, size_t data_size,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPPictureInitInternal(WebPPicture* const picture, int version) {
|
||||
if (version != WEBP_ENCODER_ABI_VERSION) {
|
||||
int WebPPictureInitInternal(WebPPicture* picture, int version) {
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) {
|
||||
return 0; // caller/system version mismatch!
|
||||
}
|
||||
if (picture != NULL) {
|
||||
@ -328,7 +328,7 @@ int WebPReportProgress(const WebPPicture* const pic,
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int WebPEncode(const WebPConfig* const config, WebPPicture* const pic) {
|
||||
int WebPEncode(const WebPConfig* config, WebPPicture* pic) {
|
||||
int ok;
|
||||
|
||||
if (pic == NULL)
|
||||
|
@ -623,16 +623,15 @@ static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) {
|
||||
dmux->mem_ = *mem;
|
||||
}
|
||||
|
||||
WebPDemuxer* WebPDemuxInternal(
|
||||
const WebPData* const data, int allow_partial,
|
||||
WebPDemuxState* const state, int version) {
|
||||
WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial,
|
||||
WebPDemuxState* state, int version) {
|
||||
const ChunkParser* parser;
|
||||
int partial;
|
||||
ParseStatus status = PARSE_ERROR;
|
||||
MemBuffer mem;
|
||||
WebPDemuxer* dmux;
|
||||
|
||||
if (version != WEBP_DEMUX_ABI_VERSION) return NULL;
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DEMUX_ABI_VERSION)) return NULL;
|
||||
if (data == NULL || data->bytes_ == NULL || data->size_ == 0) return NULL;
|
||||
|
||||
if (!InitMemBuffer(&mem, data->bytes_, data->size_)) return NULL;
|
||||
@ -662,7 +661,7 @@ WebPDemuxer* WebPDemuxInternal(
|
||||
return dmux;
|
||||
}
|
||||
|
||||
void WebPDemuxDelete(WebPDemuxer* const dmux) {
|
||||
void WebPDemuxDelete(WebPDemuxer* dmux) {
|
||||
Chunk* c;
|
||||
Frame* f;
|
||||
if (dmux == NULL) return;
|
||||
@ -682,8 +681,7 @@ void WebPDemuxDelete(WebPDemuxer* const dmux) {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
uint32_t WebPDemuxGetI(const WebPDemuxer* const dmux,
|
||||
WebPFormatFeature feature) {
|
||||
uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) {
|
||||
if (dmux == NULL) return 0;
|
||||
|
||||
switch (feature) {
|
||||
@ -784,8 +782,7 @@ static int SetFrame(int frame_num, WebPIterator* const iter) {
|
||||
return SynthesizeFrame(dmux, frame, 1, iter);
|
||||
}
|
||||
|
||||
int WebPDemuxGetFrame(const WebPDemuxer* const dmux,
|
||||
int frame, WebPIterator* const iter) {
|
||||
int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) {
|
||||
if (iter == NULL) return 0;
|
||||
|
||||
memset(iter, 0, sizeof(*iter));
|
||||
@ -793,18 +790,18 @@ int WebPDemuxGetFrame(const WebPDemuxer* const dmux,
|
||||
return SetFrame(frame, iter);
|
||||
}
|
||||
|
||||
int WebPDemuxNextFrame(WebPIterator* const iter) {
|
||||
int WebPDemuxNextFrame(WebPIterator* iter) {
|
||||
if (iter == NULL) return 0;
|
||||
return SetFrame(iter->frame_num_ + 1, iter);
|
||||
}
|
||||
|
||||
int WebPDemuxPrevFrame(WebPIterator* const iter) {
|
||||
int WebPDemuxPrevFrame(WebPIterator* iter) {
|
||||
if (iter == NULL) return 0;
|
||||
if (iter->frame_num_ <= 1) return 0;
|
||||
return SetFrame(iter->frame_num_ - 1, iter);
|
||||
}
|
||||
|
||||
int WebPDemuxSelectTile(WebPIterator* const iter, int tile) {
|
||||
int WebPDemuxSelectTile(WebPIterator* iter, int tile) {
|
||||
if (iter != NULL && iter->private_ != NULL && tile > 0) {
|
||||
const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
|
||||
const Frame* const frame = GetFrame(dmux, iter->frame_num_);
|
||||
@ -815,7 +812,7 @@ int WebPDemuxSelectTile(WebPIterator* const iter, int tile) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WebPDemuxReleaseIterator(WebPIterator* const iter) {
|
||||
void WebPDemuxReleaseIterator(WebPIterator* iter) {
|
||||
(void)iter;
|
||||
}
|
||||
|
||||
@ -868,9 +865,9 @@ static int SetChunk(const char fourcc[4], int chunk_num,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebPDemuxGetChunk(const WebPDemuxer* const dmux,
|
||||
int WebPDemuxGetChunk(const WebPDemuxer* dmux,
|
||||
const char fourcc[4], int chunk_num,
|
||||
WebPChunkIterator* const iter) {
|
||||
WebPChunkIterator* iter) {
|
||||
if (iter == NULL) return 0;
|
||||
|
||||
memset(iter, 0, sizeof(*iter));
|
||||
@ -878,7 +875,7 @@ int WebPDemuxGetChunk(const WebPDemuxer* const dmux,
|
||||
return SetChunk(fourcc, chunk_num, iter);
|
||||
}
|
||||
|
||||
int WebPDemuxNextChunk(WebPChunkIterator* const iter) {
|
||||
int WebPDemuxNextChunk(WebPChunkIterator* iter) {
|
||||
if (iter != NULL) {
|
||||
const char* const fourcc =
|
||||
(const char*)iter->chunk_.bytes_ - CHUNK_HEADER_SIZE;
|
||||
@ -887,7 +884,7 @@ int WebPDemuxNextChunk(WebPChunkIterator* const iter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebPDemuxPrevChunk(WebPChunkIterator* const iter) {
|
||||
int WebPDemuxPrevChunk(WebPChunkIterator* iter) {
|
||||
if (iter != NULL && iter->chunk_num_ > 1) {
|
||||
const char* const fourcc =
|
||||
(const char*)iter->chunk_.bytes_ - CHUNK_HEADER_SIZE;
|
||||
@ -896,7 +893,7 @@ int WebPDemuxPrevChunk(WebPChunkIterator* const iter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WebPDemuxReleaseChunkIterator(WebPChunkIterator* const iter) {
|
||||
void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) {
|
||||
(void)iter;
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,14 @@ static void MuxInit(WebPMux* const mux) {
|
||||
}
|
||||
|
||||
WebPMux* WebPNewInternal(int version) {
|
||||
WebPMux* const mux = (version == WEBP_MUX_ABI_VERSION) ?
|
||||
(WebPMux*)malloc(sizeof(WebPMux)) : NULL;
|
||||
// If mux is NULL MuxInit is a noop.
|
||||
MuxInit(mux);
|
||||
return mux;
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
|
||||
return NULL;
|
||||
} else {
|
||||
WebPMux* const mux = (WebPMux*)malloc(sizeof(WebPMux));
|
||||
// If mux is NULL MuxInit is a noop.
|
||||
MuxInit(mux);
|
||||
return mux;
|
||||
}
|
||||
}
|
||||
|
||||
static void DeleteAllChunks(WebPChunk** const chunk_list) {
|
||||
@ -49,7 +52,7 @@ static void MuxRelease(WebPMux* const mux) {
|
||||
DeleteAllChunks(&mux->unknown_);
|
||||
}
|
||||
|
||||
void WebPMuxDelete(WebPMux* const mux) {
|
||||
void WebPMuxDelete(WebPMux* mux) {
|
||||
// If mux is NULL MuxRelease is a noop.
|
||||
MuxRelease(mux);
|
||||
free(mux);
|
||||
@ -202,8 +205,8 @@ static WebPMuxError DeleteLoopCount(WebPMux* const mux) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Set API(s).
|
||||
|
||||
WebPMuxError WebPMuxSetImage(WebPMux* const mux,
|
||||
const WebPData* const bitstream, int copy_data) {
|
||||
WebPMuxError WebPMuxSetImage(WebPMux* mux,
|
||||
const WebPData* bitstream, int copy_data) {
|
||||
WebPMuxError err;
|
||||
WebPChunk chunk;
|
||||
WebPMuxImage wpi;
|
||||
@ -257,8 +260,7 @@ WebPMuxError WebPMuxSetImage(WebPMux* const mux,
|
||||
return err;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxSetMetadata(WebPMux* const mux,
|
||||
const WebPData* const metadata,
|
||||
WebPMuxError WebPMuxSetMetadata(WebPMux* mux, const WebPData* metadata,
|
||||
int copy_data) {
|
||||
WebPMuxError err;
|
||||
|
||||
@ -275,8 +277,7 @@ WebPMuxError WebPMuxSetMetadata(WebPMux* const mux,
|
||||
return MuxSet(mux, IDX_META, 1, metadata, copy_data);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxSetColorProfile(WebPMux* const mux,
|
||||
const WebPData* const color_profile,
|
||||
WebPMuxError WebPMuxSetColorProfile(WebPMux* mux, const WebPData* color_profile,
|
||||
int copy_data) {
|
||||
WebPMuxError err;
|
||||
|
||||
@ -293,7 +294,7 @@ WebPMuxError WebPMuxSetColorProfile(WebPMux* const mux,
|
||||
return MuxSet(mux, IDX_ICCP, 1, color_profile, copy_data);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxSetLoopCount(WebPMux* const mux, int loop_count) {
|
||||
WebPMuxError WebPMuxSetLoopCount(WebPMux* mux, int loop_count) {
|
||||
WebPMuxError err;
|
||||
uint8_t* data = NULL;
|
||||
|
||||
@ -396,16 +397,14 @@ static WebPMuxError MuxPushFrameTileInternal(
|
||||
return err;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxPushFrame(WebPMux* const mux,
|
||||
const WebPData* const bitstream,
|
||||
WebPMuxError WebPMuxPushFrame(WebPMux* mux, const WebPData* bitstream,
|
||||
int x_offset, int y_offset,
|
||||
int duration, int copy_data) {
|
||||
return MuxPushFrameTileInternal(mux, bitstream, x_offset, y_offset,
|
||||
duration, copy_data, kChunks[IDX_FRAME].tag);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxPushTile(WebPMux* const mux,
|
||||
const WebPData* const bitstream,
|
||||
WebPMuxError WebPMuxPushTile(WebPMux* mux, const WebPData* bitstream,
|
||||
int x_offset, int y_offset,
|
||||
int copy_data) {
|
||||
return MuxPushFrameTileInternal(mux, bitstream, x_offset, y_offset,
|
||||
@ -416,7 +415,7 @@ WebPMuxError WebPMuxPushTile(WebPMux* const mux,
|
||||
//------------------------------------------------------------------------------
|
||||
// Delete API(s).
|
||||
|
||||
WebPMuxError WebPMuxDeleteImage(WebPMux* const mux) {
|
||||
WebPMuxError WebPMuxDeleteImage(WebPMux* mux) {
|
||||
WebPMuxError err;
|
||||
|
||||
if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
|
||||
@ -429,11 +428,11 @@ WebPMuxError WebPMuxDeleteImage(WebPMux* const mux) {
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxDeleteMetadata(WebPMux* const mux) {
|
||||
WebPMuxError WebPMuxDeleteMetadata(WebPMux* mux) {
|
||||
return MuxDeleteAllNamedData(mux, IDX_META);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxDeleteColorProfile(WebPMux* const mux) {
|
||||
WebPMuxError WebPMuxDeleteColorProfile(WebPMux* mux) {
|
||||
return MuxDeleteAllNamedData(mux, IDX_ICCP);
|
||||
}
|
||||
|
||||
@ -446,11 +445,11 @@ static WebPMuxError DeleteFrameTileInternal(WebPMux* const mux, uint32_t nth,
|
||||
return MuxImageDeleteNth(&mux->images_, nth, id);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxDeleteFrame(WebPMux* const mux, uint32_t nth) {
|
||||
WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth) {
|
||||
return DeleteFrameTileInternal(mux, nth, IDX_FRAME);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth) {
|
||||
WebPMuxError WebPMuxDeleteTile(WebPMux* mux, uint32_t nth) {
|
||||
return DeleteFrameTileInternal(mux, nth, IDX_TILE);
|
||||
}
|
||||
|
||||
@ -644,8 +643,7 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
|
||||
return err;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxAssemble(WebPMux* const mux,
|
||||
WebPData* const assembled_data) {
|
||||
WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
||||
size_t size = 0;
|
||||
uint8_t* data = NULL;
|
||||
uint8_t* dst = NULL;
|
||||
|
@ -212,20 +212,20 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Manipulation of a WebPData object.
|
||||
|
||||
void WebPDataInit(WebPData* const webp_data) {
|
||||
void WebPDataInit(WebPData* webp_data) {
|
||||
if (webp_data != NULL) {
|
||||
memset(webp_data, 0, sizeof(*webp_data));
|
||||
}
|
||||
}
|
||||
|
||||
void WebPDataClear(WebPData* const webp_data) {
|
||||
void WebPDataClear(WebPData* webp_data) {
|
||||
if (webp_data != NULL) {
|
||||
free((void*)webp_data->bytes_);
|
||||
WebPDataInit(webp_data);
|
||||
}
|
||||
}
|
||||
|
||||
int WebPDataCopy(const WebPData* const src, WebPData* const dst) {
|
||||
int WebPDataCopy(const WebPData* src, WebPData* dst) {
|
||||
if (src == NULL || dst == NULL) return 0;
|
||||
|
||||
WebPDataInit(dst);
|
||||
|
@ -76,7 +76,7 @@ static WebPMuxError ChunkVerifyAndAssignData(WebPChunk* chunk,
|
||||
//------------------------------------------------------------------------------
|
||||
// Create a mux object from WebP-RIFF data.
|
||||
|
||||
WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
||||
WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
|
||||
int version) {
|
||||
size_t riff_size;
|
||||
uint32_t tag;
|
||||
@ -89,7 +89,9 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
||||
ChunkInit(&chunk);
|
||||
|
||||
// Sanity checks.
|
||||
if (version != WEBP_MUX_ABI_VERSION) return NULL; // version mismatch
|
||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
|
||||
return NULL; // version mismatch
|
||||
}
|
||||
if (bitstream == NULL) return NULL;
|
||||
|
||||
data = bitstream->bytes_;
|
||||
@ -188,7 +190,7 @@ WebPMux* WebPMuxCreateInternal(const WebPData* const bitstream, int copy_data,
|
||||
//------------------------------------------------------------------------------
|
||||
// Get API(s).
|
||||
|
||||
WebPMuxError WebPMuxGetFeatures(const WebPMux* const mux, uint32_t* flags) {
|
||||
WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) {
|
||||
WebPData data;
|
||||
WebPMuxError err;
|
||||
|
||||
@ -268,8 +270,7 @@ static WebPMuxError SynthesizeBitstream(WebPMuxImage* const wpi,
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxGetImage(const WebPMux* const mux,
|
||||
WebPData* const bitstream) {
|
||||
WebPMuxError WebPMuxGetImage(const WebPMux* mux, WebPData* bitstream) {
|
||||
WebPMuxError err;
|
||||
WebPMuxImage* wpi = NULL;
|
||||
|
||||
@ -288,20 +289,18 @@ WebPMuxError WebPMuxGetImage(const WebPMux* const mux,
|
||||
return SynthesizeBitstream(wpi, bitstream);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxGetMetadata(const WebPMux* const mux,
|
||||
WebPData* const metadata) {
|
||||
WebPMuxError WebPMuxGetMetadata(const WebPMux* mux, WebPData* metadata) {
|
||||
if (mux == NULL || metadata == NULL) return WEBP_MUX_INVALID_ARGUMENT;
|
||||
return MuxGet(mux, IDX_META, 1, metadata);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxGetColorProfile(const WebPMux* const mux,
|
||||
WebPData* const color_profile) {
|
||||
WebPMuxError WebPMuxGetColorProfile(const WebPMux* mux,
|
||||
WebPData* color_profile) {
|
||||
if (mux == NULL || color_profile == NULL) return WEBP_MUX_INVALID_ARGUMENT;
|
||||
return MuxGet(mux, IDX_ICCP, 1, color_profile);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxGetLoopCount(const WebPMux* const mux,
|
||||
int* const loop_count) {
|
||||
WebPMuxError WebPMuxGetLoopCount(const WebPMux* mux, int* loop_count) {
|
||||
WebPData image;
|
||||
WebPMuxError err;
|
||||
|
||||
@ -348,16 +347,16 @@ static WebPMuxError MuxGetFrameTileInternal(
|
||||
return SynthesizeBitstream(wpi, bitstream);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxGetFrame(const WebPMux* const mux, uint32_t nth,
|
||||
WebPData* const bitstream, int* const x_offset,
|
||||
int* const y_offset, int* const duration) {
|
||||
WebPMuxError WebPMuxGetFrame(const WebPMux* mux, uint32_t nth,
|
||||
WebPData* bitstream,
|
||||
int* x_offset, int* y_offset, int* duration) {
|
||||
return MuxGetFrameTileInternal(mux, nth, bitstream, x_offset, y_offset,
|
||||
duration, kChunks[IDX_FRAME].tag);
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxGetTile(const WebPMux* const mux, uint32_t nth,
|
||||
WebPData* const bitstream,
|
||||
int* const x_offset, int* const y_offset) {
|
||||
WebPMuxError WebPMuxGetTile(const WebPMux* mux, uint32_t nth,
|
||||
WebPData* bitstream,
|
||||
int* x_offset, int* y_offset) {
|
||||
return MuxGetFrameTileInternal(mux, nth, bitstream, x_offset, y_offset, NULL,
|
||||
kChunks[IDX_TILE].tag);
|
||||
}
|
||||
@ -384,7 +383,7 @@ static int CountChunks(const WebPChunk* const chunk_list, uint32_t tag) {
|
||||
return count;
|
||||
}
|
||||
|
||||
WebPMuxError WebPMuxNumChunks(const WebPMux* const mux,
|
||||
WebPMuxError WebPMuxNumChunks(const WebPMux* mux,
|
||||
WebPChunkId id, int* num_elements) {
|
||||
if (mux == NULL || num_elements == NULL) {
|
||||
return WEBP_MUX_INVALID_ARGUMENT;
|
||||
|
@ -146,7 +146,7 @@ static void ShiftBytes(VP8LBitReader* const br) {
|
||||
|
||||
void VP8LFillBitWindow(VP8LBitReader* const br) {
|
||||
if (br->bit_pos_ >= 32) {
|
||||
#if defined(__x86_64__)
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
if (br->pos_ + 8 < br->len_) {
|
||||
br->val_ >>= 32;
|
||||
// The expression below needs a little-endian arch to work correctly.
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Color Cache for WebP Lossless
|
||||
//
|
||||
// Author: jyrki@google.com (Jyrki Alakuijala)
|
||||
// Author: Jyrki Alakuijala (jyrki@google.com)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -35,14 +35,10 @@ int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
|
||||
void VP8LColorCacheClear(VP8LColorCache* const cc) {
|
||||
if (cc != NULL) {
|
||||
free(cc->colors_);
|
||||
cc->colors_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VP8LColorCacheDelete(VP8LColorCache* const cc) {
|
||||
VP8LColorCacheClear(cc);
|
||||
free(cc);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -7,8 +7,8 @@
|
||||
//
|
||||
// Color Cache for WebP Lossless
|
||||
//
|
||||
// Authors: jyrki@google.com (Jyrki Alakuijala)
|
||||
// urvang@google.com (Urvang Joshi)
|
||||
// Authors: Jyrki Alakuijala (jyrki@google.com)
|
||||
// Urvang Joshi (urvang@google.com)
|
||||
|
||||
#ifndef WEBP_UTILS_COLOR_CACHE_H_
|
||||
#define WEBP_UTILS_COLOR_CACHE_H_
|
||||
@ -56,12 +56,9 @@ static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc,
|
||||
// Returns false in case of memory error.
|
||||
int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits);
|
||||
|
||||
// Delete the color cache.
|
||||
// Delete the memory associated to color cache.
|
||||
void VP8LColorCacheClear(VP8LColorCache* const color_cache);
|
||||
|
||||
// Delete the color_cache object.
|
||||
void VP8LColorCacheDelete(VP8LColorCache* const color_cache);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Utilities for building and looking up Huffman trees.
|
||||
//
|
||||
// Author: urvang@google.com (Urvang Joshi)
|
||||
// Author: Urvang Joshi (urvang@google.com)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Utilities for building and looking up Huffman trees.
|
||||
//
|
||||
// Author: urvang@google.com (Urvang Joshi)
|
||||
// Author: Urvang Joshi (urvang@google.com)
|
||||
|
||||
#ifndef WEBP_UTILS_HUFFMAN_H_
|
||||
#define WEBP_UTILS_HUFFMAN_H_
|
||||
|
@ -5,9 +5,9 @@
|
||||
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Author: jyrki@google.com (Jyrki Alakuijala)
|
||||
// Author: Jyrki Alakuijala (jyrki@google.com)
|
||||
//
|
||||
// Flate-like entropy encoding (Huffman) for webp lossless.
|
||||
// Entropy encoding (Huffman) for webp lossless.
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -5,9 +5,9 @@
|
||||
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Author: jyrki@google.com (Jyrki Alakuijala)
|
||||
// Author: Jyrki Alakuijala (jyrki@google.com)
|
||||
//
|
||||
// Flate-like entropy encoding (Huffman) for webp lossless
|
||||
// Entropy encoding (Huffman) for webp lossless
|
||||
|
||||
#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
|
||||
#define WEBP_UTILS_HUFFMAN_ENCODE_H_
|
||||
|
@ -8,7 +8,7 @@
|
||||
// Quantize levels for specified number of quantization-levels ([2, 256]).
|
||||
// Min and max values are preserved (usual 0 and 255 for alpha plane).
|
||||
//
|
||||
// Author: skal@google.com (Pascal Massimino)
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h> // for sqrt()
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Alpha plane quantization utility
|
||||
//
|
||||
// Author: vikasa@google.com (Vikas Arora)
|
||||
// Author: Vikas Arora (vikasa@google.com)
|
||||
|
||||
#ifndef WEBP_UTILS_QUANT_LEVELS_H_
|
||||
#define WEBP_UTILS_QUANT_LEVELS_H_
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Rescaling functions
|
||||
//
|
||||
// Author: skal@google.com (Pascal Massimino)
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_UTILS_RESCALER_H_
|
||||
#define WEBP_UTILS_RESCALER_H_
|
||||
|
@ -7,7 +7,8 @@
|
||||
//
|
||||
// Multi-threaded worker
|
||||
//
|
||||
// Author: skal@google.com (Pascal Massimino)
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
// Multi-threaded worker
|
||||
//
|
||||
// Author: skal@google.com (Pascal Massimino)
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_UTILS_THREAD_H_
|
||||
#define WEBP_UTILS_THREAD_H_
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Main decoding functions for WEBP images.
|
||||
// Main decoding functions for WebP images.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_DECODER_ABI_VERSION 0x0003
|
||||
#define WEBP_DECODER_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Return the decoder's version number, packed in hexadecimal using 8bits for
|
||||
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
@ -27,37 +27,41 @@ WEBP_EXTERN(int) WebPGetDecoderVersion(void);
|
||||
// Retrieve basic header information: width, height.
|
||||
// This function will also validate the header and return 0 in
|
||||
// case of formatting error.
|
||||
// Pointers *width/*height can be passed NULL if deemed irrelevant.
|
||||
// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
|
||||
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 RGB samples, along
|
||||
// with the dimensions in *width and *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 free().
|
||||
// Returns NULL in case of error.
|
||||
WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGB, but returning RGBA data.
|
||||
WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
|
||||
// Same as WebPDecodeRGBA, but returning ARGB data.
|
||||
// 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);
|
||||
|
||||
// This variant decode to BGR instead of RGB.
|
||||
WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size,
|
||||
int* width, int* height);
|
||||
// This variant decodes to BGRA instead of RGBA.
|
||||
// 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);
|
||||
|
||||
// Decode WEBP images stored in *data in Y'UV format(*). The pointer returned is
|
||||
// the Y samples buffer. Upon return, *u and *v will point to the U and V
|
||||
// chroma data. These U and V buffers need NOT be free()'d, unlike the returned
|
||||
// Y luma one. The dimension of the U and V planes are both (*width + 1) / 2
|
||||
// and (*height + 1)/ 2.
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
// 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
|
||||
// the U and V chroma data. These U and V buffers need NOT be free()'d,
|
||||
// unlike the returned Y luma one. The dimension of the U and V planes
|
||||
// are both (*width + 1) / 2 and (*height + 1)/ 2.
|
||||
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
|
||||
// have a common stride returned as '*uv_stride'.
|
||||
// Return NULL in case of error.
|
||||
@ -75,20 +79,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*) 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*) 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(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
// BGR variants
|
||||
WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto(
|
||||
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);
|
||||
WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto(
|
||||
|
||||
// RGB and BGR variants. Here too the transparency information, if present,
|
||||
// will be dropped and ignored.
|
||||
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(
|
||||
const uint8_t* data, size_t data_size,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
@ -109,6 +115,10 @@ WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto(
|
||||
// Output colorspaces and buffer
|
||||
|
||||
// Colorspaces
|
||||
// Note: the naming describes the byte-ordering of packed samples in memory.
|
||||
// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
|
||||
// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
|
||||
// RGB-565 and RGBA-4444 are also endian-agnostic and byte-oriented.
|
||||
typedef enum { MODE_RGB = 0, MODE_RGBA = 1,
|
||||
MODE_BGR = 2, MODE_BGRA = 3,
|
||||
MODE_ARGB = 4, MODE_RGBA_4444 = 5,
|
||||
@ -140,7 +150,7 @@ static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecBuffer: Generic structure for describing the sample buffer.
|
||||
// WebPDecBuffer: Generic structure for describing the output sample buffer.
|
||||
|
||||
typedef struct { // view as RGBA
|
||||
uint8_t* rgba; // pointer to RGBA samples
|
||||
@ -167,23 +177,25 @@ typedef struct {
|
||||
WebPRGBABuffer RGBA;
|
||||
WebPYUVABuffer YUVA;
|
||||
} u; // Nameless union of buffer parameters.
|
||||
uint32_t pad[4]; // padding for later use
|
||||
|
||||
uint8_t* private_memory; // Internally allocated memory (only when
|
||||
// is_external_memory is false). Should not be used
|
||||
// externally, but accessed via the buffer union.
|
||||
} WebPDecBuffer;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer* const, int);
|
||||
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* const buffer) {
|
||||
static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
|
||||
return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Free any memory associated with the buffer. Must always be called last.
|
||||
// Note: doesn't free the 'buffer' structure itself.
|
||||
WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* const buffer);
|
||||
WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Enumeration of the status codes
|
||||
@ -211,7 +223,7 @@ typedef enum {
|
||||
// WebPInitDecBuffer(&buffer);
|
||||
// buffer.colorspace = mode;
|
||||
// ...
|
||||
// WebPIDecoder* const idec = WebPINewDecoder(&buffer);
|
||||
// WebPIDecoder* idec = WebPINewDecoder(&buffer);
|
||||
// while (has_more_data) {
|
||||
// // ... (get additional data)
|
||||
// status = WebPIAppend(idec, new_data, new_data_size);
|
||||
@ -233,15 +245,15 @@ typedef struct WebPIDecoder WebPIDecoder;
|
||||
// is kept, which means that the lifespan of 'output_buffer' must be larger than
|
||||
// that of the returned WebPIDecoder object.
|
||||
// Returns NULL if the allocation failed.
|
||||
WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* const output_buffer);
|
||||
WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer);
|
||||
|
||||
// This function allocates and initializes an incremental-decoder object, which
|
||||
// will output the r/g/b(/a) samples specified by 'mode' into a preallocated
|
||||
// will output the RGB/A samples specified by 'csp' into a preallocated
|
||||
// buffer 'output_buffer'. The size of this buffer is at least
|
||||
// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
|
||||
// is specified by 'output_stride'. Returns NULL if the allocation failed.
|
||||
WEBP_EXTERN(WebPIDecoder*) WebPINewRGB(
|
||||
WEBP_CSP_MODE mode,
|
||||
WEBP_CSP_MODE csp,
|
||||
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
|
||||
|
||||
// This function allocates and initializes an incremental-decoder object, which
|
||||
@ -258,13 +270,13 @@ WEBP_EXTERN(WebPIDecoder*) WebPINewYUV(
|
||||
|
||||
// Deletes the WebPIDecoder object and associated memory. Must always be called
|
||||
// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
|
||||
WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* const idec);
|
||||
WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec);
|
||||
|
||||
// Copies and decodes the next available data. Returns VP8_STATUS_OK when
|
||||
// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
|
||||
// data is expected. Returns error in other cases.
|
||||
WEBP_EXTERN(VP8StatusCode) WebPIAppend(
|
||||
WebPIDecoder* const idec, const uint8_t* const data, size_t data_size);
|
||||
WebPIDecoder* idec, const uint8_t* data, size_t data_size);
|
||||
|
||||
// A variant of the above function to be used when data buffer contains
|
||||
// partial data from the beginning. In this case data buffer is not copied
|
||||
@ -272,22 +284,22 @@ WEBP_EXTERN(VP8StatusCode) WebPIAppend(
|
||||
// Note that the value of the 'data' pointer can change between calls to
|
||||
// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
|
||||
WEBP_EXTERN(VP8StatusCode) WebPIUpdate(
|
||||
WebPIDecoder* const idec, const uint8_t* const data, size_t data_size);
|
||||
WebPIDecoder* idec, const uint8_t* data, size_t data_size);
|
||||
|
||||
// Returns the r/g/b/(a) image decoded so far. Returns NULL if output params
|
||||
// are not initialized yet. The r/g/b/(a) output type corresponds to the mode
|
||||
// specified in WebPINewDecoder()/WebPINewRGB().
|
||||
// Returns the RGB/A image decoded so far. Returns NULL if output params
|
||||
// are not initialized yet. The RGB/A output type corresponds to the colorspace
|
||||
// specified during call to WebPINewDecoder() or WebPINewRGB().
|
||||
// *last_y is the index of last decoded row in raster scan order. Some pointers
|
||||
// (*last_y, *width etc.) can be NULL if corresponding information is not
|
||||
// needed.
|
||||
WEBP_EXTERN(uint8_t*) WebPIDecGetRGB(
|
||||
const WebPIDecoder* const idec, int* last_y,
|
||||
const WebPIDecoder* idec, int* last_y,
|
||||
int* width, int* height, int* stride);
|
||||
|
||||
// Same as above function to get YUV image. Returns pointer to the luma plane
|
||||
// or NULL in case of error.
|
||||
WEBP_EXTERN(uint8_t*) WebPIDecGetYUV(
|
||||
const WebPIDecoder* const idec, int* last_y,
|
||||
const WebPIDecoder* idec, int* last_y,
|
||||
uint8_t** u, uint8_t** v,
|
||||
int* width, int* height, int* stride, int* uv_stride);
|
||||
|
||||
@ -298,9 +310,7 @@ WEBP_EXTERN(uint8_t*) WebPIDecGetYUV(
|
||||
// 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(
|
||||
const WebPIDecoder* const idec,
|
||||
int* const left, int* const top,
|
||||
int* const width, int* const height);
|
||||
const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Advanced decoding parametrization
|
||||
@ -337,19 +347,22 @@ WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea(
|
||||
|
||||
// Features gathered from the bitstream
|
||||
typedef struct {
|
||||
int width; // the original width, as read from the bitstream
|
||||
int height; // the original height, as read from the bitstream
|
||||
int has_alpha; // true if bitstream contains an alpha channel
|
||||
int width; // Width in pixels, as read from the bitstream.
|
||||
int height; // Height in pixels, as read from the bitstream.
|
||||
int has_alpha; // True if the bitstream contains an alpha channel.
|
||||
|
||||
// Unused for now:
|
||||
int bitstream_version; // should be 0 for now. TODO(later)
|
||||
int no_incremental_decoding; // if true, using incremental decoding is not
|
||||
// recommended.
|
||||
int rotate; // TODO(later)
|
||||
int uv_sampling; // should be 0 for now. TODO(later)
|
||||
int bitstream_version; // should be 0 for now. TODO(later)
|
||||
uint32_t pad[3]; // padding for later use
|
||||
} WebPBitstreamFeatures;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal(
|
||||
const uint8_t*, size_t, WebPBitstreamFeatures* const, int);
|
||||
const uint8_t*, size_t, WebPBitstreamFeatures*, int);
|
||||
|
||||
// Retrieve features from the bitstream. The *features structure is filled
|
||||
// with information gathered from the bitstream.
|
||||
@ -357,7 +370,7 @@ WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal(
|
||||
// In case of error, features->bitstream_status will reflect the error code.
|
||||
static WEBP_INLINE VP8StatusCode WebPGetFeatures(
|
||||
const uint8_t* data, size_t data_size,
|
||||
WebPBitstreamFeatures* const features) {
|
||||
WebPBitstreamFeatures* features) {
|
||||
return WebPGetFeaturesInternal(data, data_size, features,
|
||||
WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
@ -372,9 +385,12 @@ typedef struct {
|
||||
int crop_width, crop_height; // dimension of the cropping area
|
||||
int use_scaling; // if true, scaling is applied _afterward_
|
||||
int scaled_width, scaled_height; // final resolution
|
||||
int use_threads; // if true, use multi-threaded decoding
|
||||
|
||||
// Unused for now:
|
||||
int force_rotation; // forced rotation (to be applied _last_)
|
||||
int no_enhancement; // if true, discard enhancement layer
|
||||
int use_threads; // if true, use multi-threaded decoding
|
||||
uint32_t pad[6]; // padding for later use
|
||||
} WebPDecoderOptions;
|
||||
|
||||
// Main object storing the configuration for advanced decoding.
|
||||
@ -385,32 +401,32 @@ typedef struct {
|
||||
} WebPDecoderConfig;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig* const, int);
|
||||
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* const config) {
|
||||
static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
|
||||
return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Instantiate a new incremental decoder object with requested configuration.
|
||||
// The bitstream can be passed using *data and data_size parameter,
|
||||
// in which case the features will be parsed and stored into config->input.
|
||||
// Otherwise, 'data' can be NULL and now parsing will occur.
|
||||
// Note that 'config' can be NULL too, in which case a default configuration is
|
||||
// used.
|
||||
// Instantiate a new incremental decoder object with the requested
|
||||
// configuration. The bitstream can be passed using 'data' and 'data_size'
|
||||
// parameter, in which case the features will be parsed and stored into
|
||||
// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
|
||||
// Note that 'config' can be NULL too, in which case a default configuration
|
||||
// is used.
|
||||
// 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).
|
||||
WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* const config);
|
||||
WebPDecoderConfig* config);
|
||||
|
||||
// Non-incremental version. This version decodes the full data at once, taking
|
||||
// 'config' into account. Return decoding status (VP8_STATUS_OK if decoding
|
||||
// was successful).
|
||||
// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
|
||||
// if the decoding was successful).
|
||||
WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size,
|
||||
WebPDecoderConfig* const config);
|
||||
WebPDecoderConfig* config);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
|
@ -18,7 +18,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x0003
|
||||
#define WEBP_ENCODER_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Return the encoder's version number, packed in hexadecimal using 8bits for
|
||||
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
@ -30,6 +30,9 @@ WEBP_EXTERN(int) WebPGetEncoderVersion(void);
|
||||
// Returns the size of the compressed data (pointed to by *output), or 0 if
|
||||
// an error occurred. The compressed data must be released by the caller
|
||||
// using the call 'free(*output)'.
|
||||
// These functions compress using the lossy format, and the quality_factor
|
||||
// can go from 0 (smaller output, lower quality) to 100 (best quality,
|
||||
// larger output).
|
||||
WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb,
|
||||
int width, int height, int stride,
|
||||
float quality_factor, uint8_t** output);
|
||||
@ -43,6 +46,22 @@ WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra,
|
||||
int width, int height, int stride,
|
||||
float quality_factor, uint8_t** output);
|
||||
|
||||
// These functions are the equivalent of the above, but compressing in a
|
||||
// lossless manner. Files are usually larger than lossy format, but will
|
||||
// not suffer any compression loss.
|
||||
WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra,
|
||||
int width, int height, int stride,
|
||||
uint8_t** output);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Coding parameters
|
||||
|
||||
@ -54,37 +73,42 @@ typedef enum {
|
||||
} WebPImageHint;
|
||||
|
||||
typedef struct {
|
||||
float quality; // between 0 (smallest file) and 100 (biggest)
|
||||
int target_size; // if non-zero, set the desired target size in bytes.
|
||||
// Takes precedence over the 'compression' parameter.
|
||||
float target_PSNR; // if non-zero, specifies the minimal distortion to
|
||||
// try to achieve. Takes precedence over target_size.
|
||||
int method; // quality/speed trade-off (0=fast, 6=slower-better)
|
||||
int segments; // maximum number of segments to use, in [1..4]
|
||||
int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
|
||||
int filter_strength; // range: [0 = off .. 100 = strongest]
|
||||
int filter_sharpness; // range: [0 = off .. 7 = least sharp]
|
||||
int filter_type; // filtering type: 0 = simple, 1 = strong
|
||||
// (only used if filter_strength > 0 or autofilter > 0)
|
||||
int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
|
||||
int pass; // number of entropy-analysis passes (in [1..10]).
|
||||
int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
|
||||
float quality; // between 0 (smallest file) and 100 (biggest)
|
||||
int method; // quality/speed trade-off (0=fast, 6=slower-better)
|
||||
|
||||
int show_compressed; // if true, export the compressed picture back.
|
||||
// In-loop filtering is not applied.
|
||||
int preprocessing; // preprocessing filter (0=none, 1=segment-smooth)
|
||||
int partitions; // log2(number of token partitions) in [0..3]
|
||||
// Default is set to 0 for easier progressive decoding.
|
||||
int partition_limit; // quality degradation allowed to fit the 512k limit on
|
||||
// prediction modes coding (0=no degradation, 100=full)
|
||||
WebPImageHint image_hint; // Hint for image type (lossless only for now).
|
||||
|
||||
// Parameters related to lossy compression only:
|
||||
int target_size; // if non-zero, set the desired target size in bytes.
|
||||
// Takes precedence over the 'compression' parameter.
|
||||
float target_PSNR; // if non-zero, specifies the minimal distortion to
|
||||
// try to achieve. Takes precedence over target_size.
|
||||
int segments; // maximum number of segments to use, in [1..4]
|
||||
int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
|
||||
int filter_strength; // range: [0 = off .. 100 = strongest]
|
||||
int filter_sharpness; // range: [0 = off .. 7 = least sharp]
|
||||
int filter_type; // filtering type: 0 = simple, 1 = strong (only used
|
||||
// if filter_strength > 0 or autofilter > 0)
|
||||
int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
|
||||
int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
|
||||
// 1 = backward reference counts encoded with
|
||||
// arithmetic encoder). Default is 1.
|
||||
// 1 = compressed with WebP lossless). Default is 1.
|
||||
int alpha_filtering; // Predictive filtering method for alpha plane.
|
||||
// 0: none, 1: fast, 2: best. Default if 1.
|
||||
int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
|
||||
// Default is 100.
|
||||
int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
|
||||
WebPImageHint image_hint; // Hint for image type.
|
||||
int pass; // number of entropy-analysis passes (in [1..10]).
|
||||
|
||||
int show_compressed; // if true, export the compressed picture back.
|
||||
// In-loop filtering is not applied.
|
||||
int preprocessing; // preprocessing filter (0=none, 1=segment-smooth)
|
||||
int partitions; // log2(number of token partitions) in [0..3]. Default
|
||||
// is set to 0 for easier progressive decoding.
|
||||
int partition_limit; // quality degradation allowed to fit the 512k limit
|
||||
// on prediction modes coding (0: no degradation,
|
||||
// 100: maximum possible degradation).
|
||||
|
||||
uint32_t pad[8]; // padding for later use
|
||||
} WebPConfig;
|
||||
|
||||
// Enumerate some predefined settings for WebPConfig, depending on the type
|
||||
@ -99,13 +123,13 @@ typedef enum {
|
||||
} WebPPreset;
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(int) WebPConfigInitInternal(
|
||||
WebPConfig* const, WebPPreset, float, int);
|
||||
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.
|
||||
static WEBP_INLINE int WebPConfigInit(WebPConfig* const config) {
|
||||
// Note that the default values are lossless=0 and quality=75.
|
||||
static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
|
||||
return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
|
||||
WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
@ -114,7 +138,7 @@ static WEBP_INLINE int WebPConfigInit(WebPConfig* const 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* const config,
|
||||
static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
|
||||
WebPPreset preset, float quality) {
|
||||
return WebPConfigInitInternal(config, preset, quality,
|
||||
WEBP_ENCODER_ABI_VERSION);
|
||||
@ -122,17 +146,18 @@ static WEBP_INLINE int WebPConfigPreset(WebPConfig* const config,
|
||||
|
||||
// Returns true if 'config' is non-NULL and all configuration parameters are
|
||||
// within their valid ranges.
|
||||
WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* const config);
|
||||
WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Input / Output
|
||||
|
||||
typedef struct WebPPicture WebPPicture; // main structure for I/O
|
||||
|
||||
// non-essential structure for storing auxiliary statistics
|
||||
// Structure for storing auxiliary statistics (mostly for lossy encoding).
|
||||
typedef struct {
|
||||
float PSNR[4]; // peak-signal-to-noise ratio for Y/U/V/All
|
||||
int coded_size; // final size
|
||||
|
||||
float PSNR[4]; // peak-signal-to-noise ratio for Y/U/V/All
|
||||
int block_count[3]; // number of intra4/intra16/skipped macroblocks
|
||||
int header_bytes[2]; // approximate number of bytes spent for header
|
||||
// and mode-partition #0
|
||||
@ -147,13 +172,15 @@ typedef struct {
|
||||
|
||||
void* user_data; // this field is free to be set to any value and
|
||||
// used during callbacks (like progress-report e.g.).
|
||||
|
||||
uint32_t pad[6]; // padding for later use
|
||||
} WebPAuxStats;
|
||||
|
||||
// Signature for output function. Should return true if writing was successful.
|
||||
// data/data_size is the segment of data to write, and 'picture' is for
|
||||
// reference (and so one can make use of picture->custom_ptr).
|
||||
typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* const picture);
|
||||
const WebPPicture* picture);
|
||||
|
||||
// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
|
||||
// the following WebPMemoryWriter object (to be set as a custom_ptr).
|
||||
@ -161,20 +188,21 @@ typedef struct {
|
||||
uint8_t* mem; // final buffer (of size 'max_size', larger than 'size').
|
||||
size_t size; // final size
|
||||
size_t max_size; // total capacity
|
||||
uint32_t pad[1]; // padding for later use
|
||||
} WebPMemoryWriter;
|
||||
|
||||
// The following must be called first before any use.
|
||||
WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* const writer);
|
||||
WEBP_EXTERN(void) WebPMemoryWriterInit(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.
|
||||
WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* const picture);
|
||||
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
|
||||
// everything is OK.
|
||||
typedef int (*WebPProgressHook)(int percent, const WebPPicture* const picture);
|
||||
typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
|
||||
|
||||
typedef enum {
|
||||
// chroma sampling
|
||||
@ -210,20 +238,38 @@ typedef enum {
|
||||
// maximum width/height allowed (inclusive), in pixels
|
||||
#define WEBP_MAX_DIMENSION 16383
|
||||
|
||||
// Main exchange structure (input samples, output bytes, statistics)
|
||||
struct WebPPicture {
|
||||
// input
|
||||
|
||||
// INPUT
|
||||
//////////////
|
||||
// Main flag for encoder selecting between ARGB or YUV input.
|
||||
// It is recommended to use ARGB input (*argb, argb_stride) for lossless
|
||||
// compression, and YUV input (*y, *u, *v, etc.) for lossy compression
|
||||
// since these are the respective native colorspace for these formats.
|
||||
int use_argb;
|
||||
|
||||
// YUV input (mostly used for input to lossy compression)
|
||||
WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr).
|
||||
int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
|
||||
uint8_t *y, *u, *v; // pointers to luma/chroma planes.
|
||||
int y_stride, uv_stride; // luma/chroma strides.
|
||||
uint8_t* a; // pointer to the alpha plane
|
||||
int a_stride; // stride of the alpha plane
|
||||
uint32_t pad1[2]; // padding for later use
|
||||
|
||||
// output
|
||||
// ARGB input (mostly used for input to lossless compression)
|
||||
uint32_t* argb; // Pointer to argb (32 bit) plane.
|
||||
int argb_stride; // This is stride in pixels units, not bytes.
|
||||
uint32_t pad2[3]; // padding for later use
|
||||
|
||||
// OUTPUT
|
||||
///////////////
|
||||
// Byte-emission hook, to store compressed bytes as they are ready.
|
||||
WebPWriterFunction writer; // can be NULL
|
||||
void* custom_ptr; // can be used by the writer.
|
||||
|
||||
// map for extra information
|
||||
// map for extra information (only for lossy compression mode)
|
||||
int extra_info_type; // 1: intra type, 2: segment, 3: quant
|
||||
// 4: intra-16 prediction mode,
|
||||
// 5: chroma prediction mode,
|
||||
@ -233,33 +279,40 @@ struct WebPPicture {
|
||||
// will be filled with a macroblock map, depending
|
||||
// on extra_info_type.
|
||||
|
||||
// where to store statistics, if not NULL:
|
||||
// STATS AND REPORTS
|
||||
///////////////////////////
|
||||
// Pointer to side statistics (updated only if not NULL)
|
||||
WebPAuxStats* stats;
|
||||
|
||||
// original samples (for non-YUV420 modes)
|
||||
// Error code for the latest error encountered during encoding
|
||||
WebPEncodingError error_code;
|
||||
|
||||
// If not NULL, report progress during encoding.
|
||||
WebPProgressHook progress_hook;
|
||||
|
||||
uint32_t pad3[3]; // padding for later use
|
||||
|
||||
// Unused for now: original samples (for non-YUV420 modes)
|
||||
uint8_t *u0, *v0;
|
||||
int uv0_stride;
|
||||
|
||||
WebPEncodingError error_code; // error code in case of problem.
|
||||
uint32_t pad4[7]; // padding for later use
|
||||
|
||||
WebPProgressHook progress_hook; // if not NULL, called while encoding.
|
||||
|
||||
int use_argb_input; // Flag for encoder to use argb pixels as input.
|
||||
uint32_t* argb; // Pointer to argb (32 bit) plane.
|
||||
int argb_stride; // This is stride in pixels units, not bytes.
|
||||
|
||||
// private fields:
|
||||
// PRIVATE FIELDS
|
||||
////////////////////
|
||||
void* memory_; // row chunk of memory for yuva planes
|
||||
void* memory_argb_; // and for argb too.
|
||||
void* pad5[2]; // padding for later use
|
||||
};
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture* const, int);
|
||||
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.
|
||||
static WEBP_INLINE int WebPPictureInit(WebPPicture* const picture) {
|
||||
// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
|
||||
static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
|
||||
return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -270,25 +323,26 @@ static WEBP_INLINE int WebPPictureInit(WebPPicture* const 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* const picture);
|
||||
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'
|
||||
// object itself.
|
||||
WEBP_EXTERN(void) WebPPictureFree(WebPPicture* const picture);
|
||||
// Besides memory (which is reclaimed) all other fields of 'picture' are
|
||||
// preserved.
|
||||
WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture);
|
||||
|
||||
// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return,
|
||||
// *dst will fully own the copied pixels (this is not a view).
|
||||
// Returns false in case of memory allocation error.
|
||||
WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* const src,
|
||||
WebPPicture* const dst);
|
||||
WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
|
||||
|
||||
// Compute PSNR or SSIM distortion between two pictures.
|
||||
// Result is in dB, stores in result[] in the Y/U/V/Alpha/All order.
|
||||
// Returns false in case of error (pic1 and pic2 don't have same dimension, ...)
|
||||
// Warning: this function is rather CPU-intensive.
|
||||
WEBP_EXTERN(int) WebPPictureDistortion(
|
||||
const WebPPicture* const pic1, const WebPPicture* const pic2,
|
||||
const WebPPicture* pic1, const WebPPicture* pic2,
|
||||
int metric_type, // 0 = PSNR, 1 = SSIM
|
||||
float result[5]);
|
||||
|
||||
@ -300,7 +354,7 @@ 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* const picture,
|
||||
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
|
||||
@ -312,68 +366,67 @@ WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* const picture,
|
||||
// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
|
||||
// the original dimension will be lost).
|
||||
// Returns false in case of memory allocation error or invalid parameters.
|
||||
WEBP_EXTERN(int) WebPPictureView(const WebPPicture* const src,
|
||||
WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src,
|
||||
int left, int top, int width, int height,
|
||||
WebPPicture* const dst);
|
||||
WebPPicture* dst);
|
||||
|
||||
// Returns true if the 'picture' is actually a view and therefore does
|
||||
// not own the memory for pixels.
|
||||
WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* const picture);
|
||||
WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture);
|
||||
|
||||
// Rescale a picture to new dimension width x height.
|
||||
// Now gamma correction is applied.
|
||||
// Returns false in case of error (invalid parameter or insufficient memory).
|
||||
WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* const pic,
|
||||
int width, int height);
|
||||
WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, 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(
|
||||
WebPPicture* const picture, const uint8_t* const rgb, int rgb_stride);
|
||||
WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
|
||||
// Same, but for RGBA buffer.
|
||||
WEBP_EXTERN(int) WebPPictureImportRGBA(
|
||||
WebPPicture* const picture, const uint8_t* const rgba, int rgba_stride);
|
||||
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(
|
||||
WebPPicture* const picture, const uint8_t* const rgbx, int rgbx_stride);
|
||||
WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
|
||||
|
||||
// Variants of the above, but taking BGR(A|X) input.
|
||||
WEBP_EXTERN(int) WebPPictureImportBGR(
|
||||
WebPPicture* const picture, const uint8_t* const bgr, int bgr_stride);
|
||||
WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
|
||||
WEBP_EXTERN(int) WebPPictureImportBGRA(
|
||||
WebPPicture* const picture, const uint8_t* const bgra, int bgra_stride);
|
||||
WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
|
||||
WEBP_EXTERN(int) WebPPictureImportBGRX(
|
||||
WebPPicture* const picture, const uint8_t* const bgrx, int bgrx_stride);
|
||||
WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
|
||||
|
||||
// Converts picture->argb data to the YUVA format specified by 'colorspace'.
|
||||
// Upon return, picture->use_argb_input is set to false. The presence of
|
||||
// real non-opaque transparent values is detected, and 'colorspace' will be
|
||||
// Upon return, picture->use_argb is set to false. The presence of real
|
||||
// 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* const picture,
|
||||
WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture,
|
||||
WebPEncCSP colorspace);
|
||||
|
||||
// Converts picture->yuv to picture->argb and sets picture->use_argb_input
|
||||
// to true. The input format must be YUV_420 or YUV_420A.
|
||||
// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
|
||||
// The input format must be YUV_420 or YUV_420A.
|
||||
// Note that the use of this method is discouraged if one has access to the
|
||||
// raw ARGB samples, since using YUV420 is comparatively lossy. Also, the
|
||||
// conversion from YUV420 to ARGB incurs a small loss too.
|
||||
// Returns false in case of error.
|
||||
WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* const picture);
|
||||
WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture);
|
||||
|
||||
// Helper function: given a width x height plane of YUV(A) samples
|
||||
// (with stride 'stride'), clean-up the YUV samples under fully transparent
|
||||
// area, to help compressibility (no guarantee, though).
|
||||
WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* const picture);
|
||||
WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture);
|
||||
|
||||
// Scan the picture 'picture' for the presence of non fully opaque alpha values.
|
||||
// Returns true in such case. Otherwise returns false (indicating that the
|
||||
// alpha plane can be ignored altogether e.g.).
|
||||
WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* const picture);
|
||||
WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main call
|
||||
@ -384,12 +437,11 @@ WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* const picture);
|
||||
// Returns false in case of error, true otherwise.
|
||||
// In case of error, picture->error_code is updated accordingly.
|
||||
// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
|
||||
// on the value of 'picture->use_argb_input'. It is highly recommended to
|
||||
// use the former for lossy encoding, and the latter for lossless encoding
|
||||
// on the value of 'picture->use_argb'. It is highly recommended to use
|
||||
// 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* const config,
|
||||
WebPPicture* const picture);
|
||||
WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -40,6 +40,9 @@
|
||||
#define NUM_DISTANCE_CODES 40
|
||||
#define CODE_LENGTH_CODES 19
|
||||
|
||||
#define MIN_HUFFMAN_BITS 2 // min number of Huffman bits
|
||||
#define MAX_HUFFMAN_BITS 9 // max number of Huffman bits
|
||||
|
||||
#define TRANSFORM_PRESENT 1 // The bit to be written when next data
|
||||
// to be read is a transform.
|
||||
#define NUM_TRANSFORMS 4 // Maximum number of allowed transform
|
||||
|
115
src/webp/mux.h
115
src/webp/mux.h
@ -51,7 +51,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBP_MUX_ABI_VERSION 0x0000
|
||||
#define WEBP_MUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
// Error codes
|
||||
typedef enum {
|
||||
@ -99,15 +99,15 @@ typedef struct {
|
||||
// Manipulation of a WebPData object.
|
||||
|
||||
// Initializes the contents of the 'webp_data' object with default values.
|
||||
WEBP_EXTERN(void) WebPDataInit(WebPData* const webp_data);
|
||||
WEBP_EXTERN(void) WebPDataInit(WebPData* webp_data);
|
||||
|
||||
// Clears the contents of the 'webp_data' object by calling free(). Does not
|
||||
// deallocate the object itself.
|
||||
WEBP_EXTERN(void) WebPDataClear(WebPData* const webp_data);
|
||||
WEBP_EXTERN(void) WebPDataClear(WebPData* webp_data);
|
||||
|
||||
// Allocates necessary storage for 'dst' and copies the contents of 'src'.
|
||||
// Returns true on success.
|
||||
WEBP_EXTERN(int) WebPDataCopy(const WebPData* const src, WebPData* const dst);
|
||||
WEBP_EXTERN(int) WebPDataCopy(const WebPData* src, WebPData* dst);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Life of a Mux object
|
||||
@ -125,13 +125,13 @@ static WEBP_INLINE WebPMux* WebPMuxNew(void) {
|
||||
// Deletes the mux object.
|
||||
// Parameters:
|
||||
// mux - (in/out) object to be deleted
|
||||
WEBP_EXTERN(void) WebPMuxDelete(WebPMux* const mux);
|
||||
WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Mux creation.
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData* const, int, int);
|
||||
WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int);
|
||||
|
||||
// Creates a mux object from raw data given in WebP RIFF format.
|
||||
// Parameters:
|
||||
@ -141,7 +141,7 @@ WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData* const, 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* const bitstream,
|
||||
static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
|
||||
int copy_data) {
|
||||
return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
|
||||
}
|
||||
@ -161,8 +161,9 @@ static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* const bitstream,
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(
|
||||
WebPMux* const mux, const WebPData* const bitstream, int copy_data);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(WebPMux* mux,
|
||||
const WebPData* bitstream,
|
||||
int copy_data);
|
||||
|
||||
// Gets image data from the mux object.
|
||||
// The content of 'bitstream' is allocated using malloc(), and NOT
|
||||
@ -176,8 +177,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(
|
||||
// OR mux contains animation/tiling.
|
||||
// WEBP_MUX_NOT_FOUND - if image is not present in mux object.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetImage(const WebPMux* const mux,
|
||||
WebPData* const bitstream);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetImage(const WebPMux* mux,
|
||||
WebPData* bitstream);
|
||||
|
||||
// Deletes the image in the mux object.
|
||||
// Parameters:
|
||||
@ -187,7 +188,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetImage(const WebPMux* const mux,
|
||||
// OR if mux contains animation/tiling.
|
||||
// WEBP_MUX_NOT_FOUND - if image is not present in mux object.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteImage(WebPMux* const mux);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteImage(WebPMux* mux);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// XMP Metadata.
|
||||
@ -203,8 +204,9 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteImage(WebPMux* const mux);
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if mux or metadata is NULL.
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetMetadata(
|
||||
WebPMux* const mux, const WebPData* const metadata, int copy_data);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetMetadata(WebPMux* mux,
|
||||
const WebPData* metadata,
|
||||
int copy_data);
|
||||
|
||||
// Gets a reference to the XMP metadata in the mux object.
|
||||
// The caller should NOT free the returned data.
|
||||
@ -215,8 +217,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetMetadata(
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if either mux or metadata is NULL.
|
||||
// WEBP_MUX_NOT_FOUND - if metadata is not present in mux object.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetMetadata(
|
||||
const WebPMux* const mux, WebPData* const metadata);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetMetadata(const WebPMux* mux,
|
||||
WebPData* metadata);
|
||||
|
||||
// Deletes the XMP metadata in the mux object.
|
||||
// Parameters:
|
||||
@ -225,7 +227,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetMetadata(
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
|
||||
// WEBP_MUX_NOT_FOUND - If mux does not contain metadata.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteMetadata(WebPMux* const mux);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteMetadata(WebPMux* mux);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ICC Color Profile.
|
||||
@ -241,8 +243,9 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteMetadata(WebPMux* const mux);
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if mux or color_profile is NULL
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error
|
||||
// WEBP_MUX_OK - on success
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetColorProfile(
|
||||
WebPMux* const mux, const WebPData* const color_profile, int copy_data);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetColorProfile(WebPMux* mux,
|
||||
const WebPData* color_profile,
|
||||
int copy_data);
|
||||
|
||||
// Gets a reference to the color profile in the mux object.
|
||||
// The caller should NOT free the returned data.
|
||||
@ -253,8 +256,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetColorProfile(
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if either mux or color_profile is NULL.
|
||||
// WEBP_MUX_NOT_FOUND - if color profile is not present in mux object.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetColorProfile(
|
||||
const WebPMux* const mux, WebPData* const color_profile);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetColorProfile(const WebPMux* mux,
|
||||
WebPData* color_profile);
|
||||
|
||||
// Deletes the color profile in the mux object.
|
||||
// Parameters:
|
||||
@ -263,7 +266,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetColorProfile(
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
|
||||
// WEBP_MUX_NOT_FOUND - If mux does not contain color profile.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* const mux);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* mux);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Animation.
|
||||
@ -286,7 +289,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* const mux);
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame(
|
||||
WebPMux* const mux, const WebPData* const bitstream,
|
||||
WebPMux* mux, const WebPData* bitstream,
|
||||
int x_offset, int y_offset, int duration, int copy_data);
|
||||
|
||||
// TODO(urvang): Create a struct as follows to reduce argument list size:
|
||||
@ -315,8 +318,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame(
|
||||
// WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(
|
||||
const WebPMux* const mux, uint32_t nth, WebPData* const bitstream,
|
||||
int* const x_offset, int* const y_offset, int* const duration);
|
||||
const WebPMux* mux, uint32_t nth, WebPData* bitstream,
|
||||
int* x_offset, int* y_offset, int* duration);
|
||||
|
||||
// Deletes an animation frame from the mux object.
|
||||
// nth=0 has a special meaning - last position.
|
||||
@ -328,7 +331,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(
|
||||
// WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
|
||||
// before deletion.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* const mux, uint32_t nth);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);
|
||||
|
||||
// Sets the animation loop count in the mux object. Any existing loop count
|
||||
// value(s) will be removed.
|
||||
@ -340,8 +343,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* const mux, uint32_t nth);
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* const mux,
|
||||
int loop_count);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* mux, int loop_count);
|
||||
|
||||
// Gets the animation loop count from the mux object.
|
||||
// Parameters:
|
||||
@ -351,8 +353,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* const mux,
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if either of mux or loop_count is NULL
|
||||
// WEBP_MUX_NOT_FOUND - if loop chunk is not present in mux object.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* const mux,
|
||||
int* const loop_count);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* mux,
|
||||
int* loop_count);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tiling.
|
||||
@ -374,7 +376,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* const mux,
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxPushTile(
|
||||
WebPMux* const mux, const WebPData* const bitstream,
|
||||
WebPMux* mux, const WebPData* bitstream,
|
||||
int x_offset, int y_offset, int copy_data);
|
||||
|
||||
// Gets the nth tile from the mux object.
|
||||
@ -395,8 +397,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxPushTile(
|
||||
// WEBP_MUX_BAD_DATA - if nth tile chunk in mux is invalid.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(
|
||||
const WebPMux* const mux, uint32_t nth, WebPData* const bitstream,
|
||||
int* const x_offset, int* const y_offset);
|
||||
const WebPMux* mux, uint32_t nth, WebPData* bitstream,
|
||||
int* x_offset, int* y_offset);
|
||||
|
||||
// Deletes a tile from the mux object.
|
||||
// nth=0 has a special meaning - last position
|
||||
@ -408,7 +410,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(
|
||||
// WEBP_MUX_NOT_FOUND - If there are less than nth tiles in the mux object
|
||||
// before deletion.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* mux, uint32_t nth);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Misc Utilities.
|
||||
@ -424,7 +426,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth);
|
||||
// WEBP_MUX_NOT_FOUND - if VP8X chunk is not present in mux object.
|
||||
// WEBP_MUX_BAD_DATA - if VP8X chunk in mux is invalid.
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* const mux,
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux,
|
||||
uint32_t* flags);
|
||||
|
||||
// Gets number of chunks having tag value tag in the mux object.
|
||||
@ -435,7 +437,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* const mux,
|
||||
// Returns:
|
||||
// WEBP_MUX_INVALID_ARGUMENT - if either mux, or num_elements is NULL
|
||||
// WEBP_MUX_OK - on success.
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* const mux,
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux,
|
||||
WebPChunkId id, int* num_elements);
|
||||
|
||||
// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
|
||||
@ -453,14 +455,14 @@ WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* const mux,
|
||||
// NULL.
|
||||
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
|
||||
// WEBP_MUX_OK - on success
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* const mux,
|
||||
WebPData* const assembled_data);
|
||||
WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux,
|
||||
WebPData* assembled_data);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Demux API.
|
||||
// Enables extraction of image and extended format data from WebP files.
|
||||
|
||||
#define WEBP_DEMUX_ABI_VERSION 0x0000
|
||||
#define WEBP_DEMUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
typedef struct WebPDemuxer WebPDemuxer;
|
||||
|
||||
@ -475,12 +477,12 @@ typedef enum {
|
||||
|
||||
// Internal, version-checked, entry point
|
||||
WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal(
|
||||
const WebPData* const, int, WebPDemuxState* const, int);
|
||||
const WebPData*, int, WebPDemuxState*, int);
|
||||
|
||||
// Parses the WebP file given by 'data'.
|
||||
// A complete WebP file must be present in 'data' for the function to succeed.
|
||||
// Returns a WebPDemuxer object on successful parse, NULL otherwise.
|
||||
static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* const data) {
|
||||
static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
|
||||
return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
|
||||
}
|
||||
|
||||
@ -488,12 +490,12 @@ static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* const data) {
|
||||
// If 'state' is non-NULL it will be set to indicate the status of the demuxer.
|
||||
// Returns a WebPDemuxer object on successful parse, NULL otherwise.
|
||||
static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
|
||||
const WebPData* const data, WebPDemuxState* const state) {
|
||||
const WebPData* data, WebPDemuxState* state) {
|
||||
return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
|
||||
}
|
||||
|
||||
// Frees memory associated with 'dmux'.
|
||||
WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* const dmux);
|
||||
WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Data/information extraction.
|
||||
@ -509,7 +511,7 @@ typedef enum {
|
||||
// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
|
||||
// returned a state > WEBP_DEMUX_PARSING_HEADER.
|
||||
WEBP_EXTERN(uint32_t) WebPDemuxGetI(
|
||||
const WebPDemuxer* const dmux, WebPFormatFeature feature);
|
||||
const WebPDemuxer* dmux, WebPFormatFeature feature);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Frame iteration.
|
||||
@ -526,6 +528,7 @@ typedef struct {
|
||||
// still be decoded with the WebP incremental decoder.
|
||||
WebPData tile_; // The frame or tile given by 'frame_num_' and 'tile_num_'.
|
||||
|
||||
uint32_t pad[4]; // padding for later use
|
||||
void* private_;
|
||||
} WebPIterator;
|
||||
|
||||
@ -537,22 +540,22 @@ typedef struct {
|
||||
// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
|
||||
// NOTE: 'dmux' must persist for the lifetime of 'iter'.
|
||||
WEBP_EXTERN(int) WebPDemuxGetFrame(
|
||||
const WebPDemuxer* const dmux, int frame_number, WebPIterator* const iter);
|
||||
const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
|
||||
|
||||
// Sets 'iter->tile_' 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* const iter);
|
||||
WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* const iter);
|
||||
WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter);
|
||||
WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter);
|
||||
|
||||
// Sets 'iter->tile_' to reflect tile number 'tile_number'.
|
||||
// Returns true if tile 'tile_number' is present, false otherwise.
|
||||
WEBP_EXTERN(int) WebPDemuxSelectTile(WebPIterator* const iter, int tile_number);
|
||||
WEBP_EXTERN(int) WebPDemuxSelectTile(WebPIterator* iter, int tile_number);
|
||||
|
||||
// Releases any memory associated with 'iter'.
|
||||
// Must be called before destroying the associated WebPDemuxer with
|
||||
// WebPDemuxDelete().
|
||||
WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* const iter);
|
||||
WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Chunk iteration.
|
||||
@ -562,9 +565,9 @@ typedef struct {
|
||||
// WebPDemuxGetChunk().
|
||||
int chunk_num_;
|
||||
int num_chunks_;
|
||||
// The payload of the chunk.
|
||||
WebPData chunk_;
|
||||
WebPData chunk_; // The payload of the chunk.
|
||||
|
||||
uint32_t pad[6]; // padding for later use
|
||||
void* private_;
|
||||
} WebPChunkIterator;
|
||||
|
||||
@ -577,20 +580,20 @@ typedef struct {
|
||||
// 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* const dmux,
|
||||
WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux,
|
||||
const char fourcc[4], int chunk_number,
|
||||
WebPChunkIterator* const iter);
|
||||
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* const iter);
|
||||
WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* const iter);
|
||||
WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter);
|
||||
WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter);
|
||||
|
||||
// Releases any memory associated with 'iter'.
|
||||
// Must be called before destroying the associated WebPDemuxer with
|
||||
// WebPDemuxDelete().
|
||||
WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* const iter);
|
||||
WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -39,4 +39,7 @@ typedef long long int int64_t;
|
||||
#define WEBP_EXTERN(type) extern type
|
||||
#endif /* WEBP_EXTERN */
|
||||
|
||||
// Macro to check ABI compatibility (same major revision number)
|
||||
#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
|
||||
|
||||
#endif /* WEBP_WEBP_TYPES_H_ */
|
||||
|
Reference in New Issue
Block a user