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:
James Zern
2012-07-21 12:20:19 -07:00
61 changed files with 1617 additions and 942 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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.

View File

@ -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_;

View File

@ -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;

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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_

View File

@ -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" {

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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>

View File

@ -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_

View File

@ -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>

View File

@ -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_

View File

@ -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()

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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"

View File

@ -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);
//------------------------------------------------------------------------------

View File

@ -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

View File

@ -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);
//------------------------------------------------------------------------------

View File

@ -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_ */