#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "src/mux/animi.h"
#include "src/utils/utils.h"
#include "src/webp/decode.h"
#include "src/webp/encode.h"
#include "src/webp/format_constants.h"
#include "src/webp/mux.h"
#include "src/webp/types.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf …
#endif
#define ERROR_STR_MAX_LENGTH …
FrameRectangle;
EncodedFrame;
struct WebPAnimEncoder { … };
#define DELTA_INFINITY …
#define KEYFRAME_NONE …
static void ResetCounters(WebPAnimEncoder* const enc) { … }
static void DisableKeyframes(WebPAnimEncoderOptions* const enc_options) { … }
#define MAX_CACHED_FRAMES …
static void SanitizeEncoderOptions(WebPAnimEncoderOptions* const enc_options) { … }
#undef MAX_CACHED_FRAMES
static void DefaultEncoderOptions(WebPAnimEncoderOptions* const enc_options) { … }
int WebPAnimEncoderOptionsInitInternal(WebPAnimEncoderOptions* enc_options,
int abi_version) { … }
#define TRANSPARENT_COLOR …
static void ClearRectangle(WebPPicture* const picture,
int left, int top, int width, int height) { … }
static void WebPUtilClearPic(WebPPicture* const picture,
const FrameRectangle* const rect) { … }
static void MarkNoError(WebPAnimEncoder* const enc) { … }
static void MarkError(WebPAnimEncoder* const enc, const char* str) { … }
static void MarkError2(WebPAnimEncoder* const enc,
const char* str, int error_code) { … }
WebPAnimEncoder* WebPAnimEncoderNewInternal(
int width, int height, const WebPAnimEncoderOptions* enc_options,
int abi_version) { … }
static void FrameRelease(EncodedFrame* const encoded_frame) { … }
void WebPAnimEncoderDelete(WebPAnimEncoder* enc) { … }
static EncodedFrame* GetFrame(const WebPAnimEncoder* const enc,
size_t position) { … }
ComparePixelsFunc;
static WEBP_INLINE int ComparePixelsLossless(const uint32_t* src, int src_step,
const uint32_t* dst, int dst_step,
int length, int max_allowed_diff) { … }
static WEBP_INLINE int PixelsAreSimilar(uint32_t src, uint32_t dst,
int max_allowed_diff) { … }
static WEBP_INLINE int ComparePixelsLossy(const uint32_t* src, int src_step,
const uint32_t* dst, int dst_step,
int length, int max_allowed_diff) { … }
static int IsEmptyRect(const FrameRectangle* const rect) { … }
static int QualityToMaxDiff(float quality) { … }
static void MinimizeChangeRectangle(const WebPPicture* const src,
const WebPPicture* const dst,
FrameRectangle* const rect,
int is_lossless, float quality) { … }
static WEBP_INLINE void SnapToEvenOffsets(FrameRectangle* const rect) { … }
SubFrameParams;
static int SubFrameParamsInit(SubFrameParams* const params,
int should_try, int empty_rect_allowed) { … }
static void SubFrameParamsFree(SubFrameParams* const params) { … }
static int GetSubRect(const WebPPicture* const prev_canvas,
const WebPPicture* const curr_canvas, int is_key_frame,
int is_first_frame, int empty_rect_allowed,
int is_lossless, float quality,
FrameRectangle* const rect,
WebPPicture* const sub_frame) { … }
static int GetSubRects(const WebPPicture* const prev_canvas,
const WebPPicture* const curr_canvas, int is_key_frame,
int is_first_frame, float quality,
SubFrameParams* const params) { … }
static WEBP_INLINE int clip(int v, int min_v, int max_v) { … }
int WebPAnimEncoderRefineRect(
const WebPPicture* const prev_canvas, const WebPPicture* const curr_canvas,
int is_lossless, float quality, int* const x_offset, int* const y_offset,
int* const width, int* const height) { … }
static void DisposeFrameRectangle(int dispose_method,
const FrameRectangle* const rect,
WebPPicture* const curr_canvas) { … }
static uint32_t RectArea(const FrameRectangle* const rect) { … }
static int IsLosslessBlendingPossible(const WebPPicture* const src,
const WebPPicture* const dst,
const FrameRectangle* const rect) { … }
static int IsLossyBlendingPossible(const WebPPicture* const src,
const WebPPicture* const dst,
const FrameRectangle* const rect,
float quality) { … }
static int IncreaseTransparency(const WebPPicture* const src,
const FrameRectangle* const rect,
WebPPicture* const dst) { … }
#undef TRANSPARENT_COLOR
static int FlattenSimilarBlocks(const WebPPicture* const src,
const FrameRectangle* const rect,
WebPPicture* const dst, float quality) { … }
static int EncodeFrame(const WebPConfig* const config, WebPPicture* const pic,
WebPMemoryWriter* const memory) { … }
Candidate;
static WebPEncodingError EncodeCandidate(WebPPicture* const sub_frame,
const FrameRectangle* const rect,
const WebPConfig* const encoder_config,
int use_blending,
Candidate* const candidate) { … }
static void CopyCurrentCanvas(WebPAnimEncoder* const enc) { … }
enum { … };
#define MIN_COLORS_LOSSY …
#define MAX_COLORS_LOSSLESS …
static WebPEncodingError GenerateCandidates(
WebPAnimEncoder* const enc, Candidate candidates[CANDIDATE_COUNT],
WebPMuxAnimDispose dispose_method, int is_lossless, int is_key_frame,
SubFrameParams* const params,
const WebPConfig* const config_ll, const WebPConfig* const config_lossy) { … }
#undef MIN_COLORS_LOSSY
#undef MAX_COLORS_LOSSLESS
static void GetEncodedData(const WebPMemoryWriter* const memory,
WebPData* const encoded_data) { … }
static void SetPreviousDisposeMethod(WebPAnimEncoder* const enc,
WebPMuxAnimDispose dispose_method) { … }
static int IncreasePreviousDuration(WebPAnimEncoder* const enc, int duration) { … }
static void PickBestCandidate(WebPAnimEncoder* const enc,
Candidate* const candidates, int is_key_frame,
EncodedFrame* const encoded_frame) { … }
static WebPEncodingError SetFrame(WebPAnimEncoder* const enc,
const WebPConfig* const config,
int is_key_frame,
EncodedFrame* const encoded_frame,
int* const frame_skipped) { … }
static int64_t KeyFramePenalty(const EncodedFrame* const encoded_frame) { … }
static int CacheFrame(WebPAnimEncoder* const enc,
const WebPConfig* const config) { … }
static int FlushFrames(WebPAnimEncoder* const enc) { … }
#undef DELTA_INFINITY
#undef KEYFRAME_NONE
int WebPAnimEncoderAdd(WebPAnimEncoder* enc, WebPPicture* frame, int timestamp,
const WebPConfig* encoder_config) { … }
WEBP_NODISCARD static int DecodeFrameOntoCanvas(
const WebPMuxFrameInfo* const frame, WebPPicture* const canvas) { … }
static int FrameToFullCanvas(WebPAnimEncoder* const enc,
const WebPMuxFrameInfo* const frame,
WebPData* const full_image) { … }
static WebPMuxError OptimizeSingleFrame(WebPAnimEncoder* const enc,
WebPData* const webp_data) { … }
int WebPAnimEncoderAssemble(WebPAnimEncoder* enc, WebPData* webp_data) { … }
const char* WebPAnimEncoderGetError(WebPAnimEncoder* enc) { … }
WebPMuxError WebPAnimEncoderSetChunk(
WebPAnimEncoder* enc, const char fourcc[4], const WebPData* chunk_data,
int copy_data) { … }
WebPMuxError WebPAnimEncoderGetChunk(
const WebPAnimEncoder* enc, const char fourcc[4], WebPData* chunk_data) { … }
WebPMuxError WebPAnimEncoderDeleteChunk(
WebPAnimEncoder* enc, const char fourcc[4]) { … }