mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-18 06:49:53 +02:00
Compare commits
15 Commits
v1.0.0-rc1
...
v1.0.0-rc3
Author | SHA1 | Date | |
---|---|---|---|
d20b770713 | |||
0d5fad46cf | |||
c1cb86af5f | |||
e577feb7c2 | |||
99be34b3a8 | |||
f5565ca84a | |||
d898dc14a5 | |||
882784b03d | |||
2f930e0872 | |||
8165e8fb3b | |||
3f157dd5e7 | |||
cd758a1745 | |||
b892b8ba8b | |||
64a57d0587 | |||
fc1b8e3a8b |
@ -10,7 +10,7 @@ option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
|
||||
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
|
||||
option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." OFF)
|
||||
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
|
||||
option(WEBP_ENABLE_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
|
||||
option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
|
||||
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
|
||||
|
||||
if(WEBP_BUILD_WEBP_JS)
|
||||
@ -289,7 +289,8 @@ if(WEBP_BUILD_WEBP_JS)
|
||||
target_link_libraries(webp_js webpdecoder SDL)
|
||||
set(WEBP_HAVE_SDL 1)
|
||||
set_target_properties(webp_js PROPERTIES LINK_FLAGS
|
||||
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0")
|
||||
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
||||
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||
|
||||
@ -299,7 +300,8 @@ if(WEBP_BUILD_WEBP_JS)
|
||||
target_link_libraries(webp_wasm webpdecoder SDL)
|
||||
set_target_properties(webp_wasm PROPERTIES LINK_FLAGS
|
||||
"-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' \
|
||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0")
|
||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||
|
||||
target_compile_definitions(webpdecoder PUBLIC EMSCRIPTEN)
|
||||
|
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
||||
0d5fad46 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
|
||||
c1cb86af fix 16b overflow in SSE2
|
||||
e577feb7 makefile.unix: add DEBUG flag for compiling w/ debug-symbol
|
||||
99be34b3 cwebp,get_disto: fix bpp output
|
||||
f5565ca8 cmake: Make sure we use near-lossless by default.
|
||||
d898dc14 fix bug in WebPImport565: alpha value was not set
|
||||
882784b0 update ChangeLog (tag: v1.0.0-rc2)
|
||||
2f930e08 Revert "Use proper targets for CMake."
|
||||
8165e8fb Use proper targets for CMake.
|
||||
3f157dd5 Remove some very hard TODOs.
|
||||
cd758a17 {de,}mux/Makefile.am: add missing headers
|
||||
b892b8ba makefile.unix,dist: use ascii for text output
|
||||
64a57d05 add -version option to anim_dump,anim_diff and img2webp
|
||||
fc1b8e3a webp_js: fix webp_js demo html
|
||||
15aa48d9 update ChangeLog (tag: v1.0.0-rc1)
|
||||
e607dabc update AUTHORS
|
||||
38410c08 [CFI] Remove function pointer casts
|
||||
c57b2736 bump version to 1.0.0
|
||||
|
3
README
3
README
@ -458,6 +458,7 @@ File-level options (only used at the start of compression):
|
||||
-mixed ............... use mixed lossy/lossless automatic mode
|
||||
-v ................... verbose mode
|
||||
-h ................... this help
|
||||
-version ............. print version number and exit
|
||||
|
||||
Per-frame options (only used for subsequent images input):
|
||||
-d <int> ............. frame duration in ms (default: 100)
|
||||
@ -527,6 +528,8 @@ Options:
|
||||
-max_diff <int> ..... maximum allowed difference per channel
|
||||
between corresponding pixels in subsequent
|
||||
frames
|
||||
-h .................. this help
|
||||
-version ............ print version number and exit
|
||||
|
||||
Building:
|
||||
---------
|
||||
|
@ -32,7 +32,8 @@ using Emscripten and CMake.
|
||||
webp.js.mem files generated.
|
||||
|
||||
The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
|
||||
bitstream into a canvas. See webp_js/index.html for a simple usage sample.
|
||||
bitstream into a canvas. See webp_js/index.html for a simple usage sample
|
||||
(see below for instructions).
|
||||
|
||||
Demo HTML page:
|
||||
===============
|
||||
|
@ -190,6 +190,8 @@ static void Help(void) {
|
||||
printf(" -max_diff <int> ..... maximum allowed difference per channel\n"
|
||||
" between corresponding pixels in subsequent\n"
|
||||
" frames\n");
|
||||
printf(" -h .................. this help\n");
|
||||
printf(" -version ............ print version number and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
@ -205,11 +207,6 @@ int main(int argc, const char* argv[]) {
|
||||
const char* files[2] = { NULL, NULL };
|
||||
AnimatedImage images[2];
|
||||
|
||||
if (argc < 3) {
|
||||
Help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-dump_frames")) {
|
||||
@ -247,6 +244,18 @@ int main(int argc, const char* argv[]) {
|
||||
} else {
|
||||
parse_error = 1;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
int dec_version, demux_version;
|
||||
GetAnimatedImageVersions(&dec_version, &demux_version);
|
||||
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
(dec_version >> 0) & 0xff,
|
||||
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
|
||||
(demux_version >> 0) & 0xff);
|
||||
return 0;
|
||||
} else {
|
||||
if (!got_input1) {
|
||||
files[0] = argv[c];
|
||||
@ -263,6 +272,12 @@ int main(int argc, const char* argv[]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (argc < 3) {
|
||||
Help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!got_input2) {
|
||||
Help();
|
||||
return -1;
|
||||
|
@ -30,6 +30,8 @@ static void Help(void) {
|
||||
"(default: 'dump_')\n");
|
||||
printf(" -tiff ............... save frames as TIFF\n");
|
||||
printf(" -pam ................ save frames as PAM\n");
|
||||
printf(" -h .................. this help\n");
|
||||
printf(" -version ............ print version number and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
@ -66,6 +68,18 @@ int main(int argc, const char* argv[]) {
|
||||
} else if (!strcmp(argv[c], "-pam")) {
|
||||
format = PAM;
|
||||
suffix = "pam";
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
int dec_version, demux_version;
|
||||
GetAnimatedImageVersions(&dec_version, &demux_version);
|
||||
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
(dec_version >> 0) & 0xff,
|
||||
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
|
||||
(demux_version >> 0) & 0xff);
|
||||
return 0;
|
||||
} else {
|
||||
uint32_t i;
|
||||
AnimatedImage image;
|
||||
|
@ -786,3 +786,9 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
||||
*psnr = 4.3429448 * log(255. * 255. / sse);
|
||||
}
|
||||
}
|
||||
|
||||
void GetAnimatedImageVersions(int* const decoder_version,
|
||||
int* const demux_version) {
|
||||
*decoder_version = WebPGetDecoderVersion();
|
||||
*demux_version = WebPGetDemuxVersion();
|
||||
}
|
||||
|
@ -56,6 +56,10 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
||||
uint32_t width, uint32_t height, int premultiply,
|
||||
int* const max_diff, double* const psnr);
|
||||
|
||||
// Return library versions used by anim_util.
|
||||
void GetAnimatedImageVersions(int* const decoder_version,
|
||||
int* const demux_version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -188,7 +188,7 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
|
||||
fprintf(stderr, "File: %s\n", file_name);
|
||||
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
|
||||
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
|
||||
1.f * stats->coded_size / pic->width / pic->height);
|
||||
8.f * stats->coded_size / pic->width / pic->height);
|
||||
PrintFullLosslessInfo(stats, "ARGB");
|
||||
}
|
||||
}
|
||||
@ -213,7 +213,7 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
||||
" (%.2f bpp)\n",
|
||||
stats->coded_size,
|
||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3],
|
||||
1.f * stats->coded_size / pic->width / pic->height);
|
||||
8.f * stats->coded_size / pic->width / pic->height);
|
||||
if (total > 0) {
|
||||
int totals[4] = { 0, 0, 0, 0 };
|
||||
fprintf(stderr, "block count: intra4: %6d (%.2f%%)\n"
|
||||
|
@ -48,6 +48,7 @@ static void Help(void) {
|
||||
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
||||
printf(" -v ................... verbose mode\n");
|
||||
printf(" -h ................... this help\n");
|
||||
printf(" -version ............. print version number and exit\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Per-frame options (only used for subsequent images input):\n");
|
||||
@ -177,6 +178,14 @@ int main(int argc, const char* argv[]) {
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
goto End;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
const int enc_version = WebPGetEncoderVersion();
|
||||
const int mux_version = WebPGetMuxVersion();
|
||||
printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
|
||||
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
|
||||
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
||||
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
||||
goto End;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -48,13 +48,14 @@ int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
|
||||
|
||||
int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||
int x, y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || rgb565 == NULL) return 0;
|
||||
pic->colorspace = WEBP_YUV420;
|
||||
pic->use_argb = 1;
|
||||
if (!WebPPictureAlloc(pic)) return 0;
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
const int width = pic->width;
|
||||
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||
for (x = 0; x < width; ++x) {
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
const uint32_t rg = rgb565[2 * x + 1];
|
||||
@ -70,22 +71,24 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||
r = r | (r >> 5);
|
||||
g = g | (g >> 6);
|
||||
b = b | (b >> 5);
|
||||
dst[x] = (r << 16) | (g << 8) | b;
|
||||
dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
rgb565 += 2 * width;
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||
int x, y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || rgb4444 == NULL) return 0;
|
||||
pic->colorspace = WEBP_YUV420;
|
||||
pic->use_argb = 1;
|
||||
if (!WebPPictureAlloc(pic)) return 0;
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
const int width = pic->width;
|
||||
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||
for (x = 0; x < width; ++x) {
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
const uint32_t rg = rgb4444[2 * x + 1];
|
||||
@ -106,6 +109,7 @@ int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
rgb4444 += 2 * width;
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ int main(int argc, const char *argv[]) {
|
||||
printf("%u %.2f %.2f %.2f %.2f %.2f [ %.2f bpp ]\n",
|
||||
(unsigned int)size1,
|
||||
disto[4], disto[0], disto[1], disto[2], disto[3],
|
||||
1.f * size1 / pic1.width / pic1.height);
|
||||
8.f * size1 / pic1.width / pic1.height);
|
||||
|
||||
if (output != NULL) {
|
||||
uint8_t* data = NULL;
|
||||
|
@ -112,7 +112,12 @@ endif
|
||||
AR = ar
|
||||
ARFLAGS = r
|
||||
CPPFLAGS = -I. -Isrc/ -Wall
|
||||
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O3 -DNDEBUG
|
||||
endif
|
||||
CFLAGS += $(EXTRA_FLAGS)
|
||||
CC = gcc
|
||||
INSTALL = install
|
||||
GROFF = /usr/bin/groff
|
||||
@ -474,7 +479,7 @@ dist: all
|
||||
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
|
||||
man/img2webp.1 man/webpinfo.1; do \
|
||||
basenam=$$(basename $$m .1); \
|
||||
$(GROFF) -t -e -man -T utf8 $$m \
|
||||
$(GROFF) -t -e -man -T ascii $$m \
|
||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
||||
$(GROFF) -t -e -man -T html $$m \
|
||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH IMG2WEBP 1 "February 7, 2018"
|
||||
.TH IMG2WEBP 1 "April 3, 2018"
|
||||
.SH NAME
|
||||
img2webp \- create animated WebP file from a sequence of input images.
|
||||
.SH SYNOPSIS
|
||||
@ -53,6 +53,9 @@ Be more verbose.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
A short usage summary.
|
||||
.TP
|
||||
.B \-version
|
||||
Print the version numbers of the relevant libraries used.
|
||||
|
||||
.SH PER-FRAME OPTIONS
|
||||
The per-frame options are applied for the images following as arguments in the
|
||||
|
@ -491,7 +491,7 @@ static int GetCoeffsAlt(VP8BitReader* const br,
|
||||
return 16;
|
||||
}
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) {
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
|
||||
if (GetCoeffs == NULL) {
|
||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||
GetCoeffs = GetCoeffsAlt;
|
||||
|
@ -5,9 +5,12 @@ libwebpdemux_la_SOURCES =
|
||||
libwebpdemux_la_SOURCES += anim_decode.c demux.c
|
||||
|
||||
libwebpdemuxinclude_HEADERS =
|
||||
libwebpdemuxinclude_HEADERS += ../webp/decode.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/demux.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/mux_types.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpdemux_la_LIBADD = ../libwebp.la
|
||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:4:0
|
||||
|
@ -409,12 +409,7 @@ extern void WebPInitAlphaProcessingSSE2(void);
|
||||
extern void WebPInitAlphaProcessingSSE41(void);
|
||||
extern void WebPInitAlphaProcessingNEON(void);
|
||||
|
||||
static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&alpha_processing_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
|
||||
if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
||||
WebPMultARGBRow = WebPMultARGBRow_C;
|
||||
WebPMultRow = WebPMultRow_C;
|
||||
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C;
|
||||
@ -474,6 +469,4 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
|
||||
assert(WebPPackRGB != NULL);
|
||||
assert(WebPHasAlpha8b != NULL);
|
||||
assert(WebPHasAlpha32b != NULL);
|
||||
|
||||
alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -378,12 +378,7 @@ extern void VP8EncDspCostInitMIPS32(void);
|
||||
extern void VP8EncDspCostInitMIPSdspR2(void);
|
||||
extern void VP8EncDspCostInitSSE2(void);
|
||||
|
||||
static volatile VP8CPUInfo cost_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&cost_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) {
|
||||
if (cost_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
||||
VP8GetResidualCost = GetResidualCost_C;
|
||||
VP8SetResidualCoeffs = SetResidualCoeffs_C;
|
||||
|
||||
@ -405,8 +400,6 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cost_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -741,12 +741,7 @@ extern void VP8DspInitMIPS32(void);
|
||||
extern void VP8DspInitMIPSdspR2(void);
|
||||
extern void VP8DspInitMSA(void);
|
||||
|
||||
static volatile VP8CPUInfo dec_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&dec_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
|
||||
if (dec_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||
VP8InitClipTables();
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
@ -889,6 +884,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
|
||||
assert(VP8PredChroma8[5] != NULL);
|
||||
assert(VP8PredChroma8[6] != NULL);
|
||||
assert(VP8DitherCombine8x8 != NULL);
|
||||
|
||||
dec_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -141,6 +141,42 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
#include <pthread.h> // NOLINT
|
||||
|
||||
#define WEBP_DSP_INIT(func) do { \
|
||||
static volatile VP8CPUInfo func ## _last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func ## _last_cpuinfo_used; \
|
||||
static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \
|
||||
if (pthread_mutex_lock(&func ## _lock)) break; \
|
||||
if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func(); \
|
||||
func ## _last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
(void)pthread_mutex_unlock(&func ## _lock); \
|
||||
} while (0)
|
||||
#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
|
||||
#define WEBP_DSP_INIT(func) do { \
|
||||
static volatile VP8CPUInfo func ## _last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func ## _last_cpuinfo_used; \
|
||||
if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break; \
|
||||
func(); \
|
||||
func ## _last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
} while (0)
|
||||
#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
|
||||
// Defines an Init + helper function that control multiple initialization of
|
||||
// function pointers / tables.
|
||||
/* Usage:
|
||||
WEBP_DSP_INIT_FUNC(InitFunc) {
|
||||
...function body
|
||||
}
|
||||
*/
|
||||
#define WEBP_DSP_INIT_FUNC(name) \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \
|
||||
WEBP_TSAN_IGNORE_FUNCTION void name(void) { \
|
||||
WEBP_DSP_INIT(name ## _body); \
|
||||
} \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void)
|
||||
|
||||
#define WEBP_UBSAN_IGNORE_UNDEF
|
||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||
#if defined(__clang__) && defined(__has_attribute)
|
||||
@ -196,7 +232,7 @@ WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
// avoiding a compiler warning.
|
||||
#define WEBP_DSP_INIT_STUB(func) \
|
||||
extern void func(void); \
|
||||
WEBP_TSAN_IGNORE_FUNCTION void func(void) {}
|
||||
void func(void) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Encoding
|
||||
|
@ -740,12 +740,7 @@ extern void VP8EncDspInitMIPS32(void);
|
||||
extern void VP8EncDspInitMIPSdspR2(void);
|
||||
extern void VP8EncDspInitMSA(void);
|
||||
|
||||
static volatile VP8CPUInfo enc_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&enc_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void) {
|
||||
if (enc_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
||||
VP8DspInit(); // common inverse transforms
|
||||
InitTables();
|
||||
|
||||
@ -838,6 +833,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void) {
|
||||
assert(VP8EncQuantizeBlockWHT != NULL);
|
||||
assert(VP8Copy4x4 != NULL);
|
||||
assert(VP8Copy16x8 != NULL);
|
||||
|
||||
enc_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -238,12 +238,7 @@ extern void VP8FiltersInitMSA(void);
|
||||
extern void VP8FiltersInitNEON(void);
|
||||
extern void VP8FiltersInitSSE2(void);
|
||||
|
||||
static volatile VP8CPUInfo filters_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&filters_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) {
|
||||
if (filters_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8FiltersInit) {
|
||||
WebPUnfilters[WEBP_FILTER_NONE] = NULL;
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_C;
|
||||
@ -289,6 +284,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) {
|
||||
assert(WebPFilters[WEBP_FILTER_HORIZONTAL] != NULL);
|
||||
assert(WebPFilters[WEBP_FILTER_VERTICAL] != NULL);
|
||||
assert(WebPFilters[WEBP_FILTER_GRADIENT] != NULL);
|
||||
|
||||
filters_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -577,9 +577,6 @@ extern void VP8LDspInitNEON(void);
|
||||
extern void VP8LDspInitMIPSdspR2(void);
|
||||
extern void VP8LDspInitMSA(void);
|
||||
|
||||
static volatile VP8CPUInfo lossless_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&lossless_last_cpuinfo_used;
|
||||
|
||||
#define COPY_PREDICTOR_ARRAY(IN, OUT) do { \
|
||||
(OUT)[0] = IN##0_C; \
|
||||
(OUT)[1] = IN##1_C; \
|
||||
@ -599,9 +596,7 @@ static volatile VP8CPUInfo lossless_last_cpuinfo_used =
|
||||
(OUT)[15] = IN##0_C; \
|
||||
} while (0);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInit(void) {
|
||||
if (lossless_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8LDspInit) {
|
||||
COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors)
|
||||
COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors_C)
|
||||
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd)
|
||||
@ -658,8 +653,6 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInit(void) {
|
||||
assert(VP8LConvertBGRAToRGB565 != NULL);
|
||||
assert(VP8LMapColor32b != NULL);
|
||||
assert(VP8LMapColor8b != NULL);
|
||||
|
||||
lossless_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
#undef COPY_PREDICTOR_ARRAY
|
||||
|
||||
|
@ -863,12 +863,7 @@ extern void VP8LEncDspInitMIPS32(void);
|
||||
extern void VP8LEncDspInitMIPSdspR2(void);
|
||||
extern void VP8LEncDspInitMSA(void);
|
||||
|
||||
static volatile VP8CPUInfo lossless_enc_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&lossless_enc_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInit(void) {
|
||||
if (lossless_enc_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
|
||||
VP8LDspInit();
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
@ -1011,8 +1006,6 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInit(void) {
|
||||
assert(VP8LPredictorsSub_C[13] != NULL);
|
||||
assert(VP8LPredictorsSub_C[14] != NULL);
|
||||
assert(VP8LPredictorsSub_C[15] != NULL);
|
||||
|
||||
lossless_enc_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -204,11 +204,7 @@ extern void WebPRescalerDspInitMIPSdspR2(void);
|
||||
extern void WebPRescalerDspInitMSA(void);
|
||||
extern void WebPRescalerDspInitNEON(void);
|
||||
|
||||
static volatile VP8CPUInfo rescaler_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&rescaler_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInit(void) {
|
||||
if (rescaler_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
WEBP_DSP_INIT_FUNC(WebPRescalerDspInit) {
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
WebPRescalerExportRowExpand = WebPRescalerExportRowExpand_C;
|
||||
@ -253,5 +249,4 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInit(void) {
|
||||
assert(WebPRescalerImportRowExpand != NULL);
|
||||
assert(WebPRescalerImportRowShrink != NULL);
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
rescaler_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ static void LoadTwoPixels_SSE2(const uint8_t* const src, __m128i* out) {
|
||||
}
|
||||
|
||||
// input: 8 bytes ABCDEFGH -> output: A0B0C0D0E0F0G0H0
|
||||
static void LoadHeightPixels_SSE2(const uint8_t* const src, __m128i* out) {
|
||||
static void LoadEightPixels_SSE2(const uint8_t* const src, __m128i* out) {
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i A = _mm_loadl_epi64((const __m128i*)(src)); // ABCDEFGH
|
||||
*out = _mm_unpacklo_epi8(A, zero);
|
||||
@ -50,13 +50,15 @@ static void RescalerImportRowExpand_SSE2(WebPRescaler* const wrk,
|
||||
int accum = x_add;
|
||||
__m128i cur_pixels;
|
||||
|
||||
// SSE2 implementation only works with 16b signed arithmetic at max.
|
||||
if (wrk->src_width < 8 || accum >= (1 << 15)) {
|
||||
WebPRescalerImportRowExpand_C(wrk, src);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!WebPRescalerInputDone(wrk));
|
||||
assert(wrk->x_expand);
|
||||
if (wrk->num_channels == 4) {
|
||||
if (wrk->src_width < 2) {
|
||||
WebPRescalerImportRowExpand_C(wrk, src);
|
||||
return;
|
||||
}
|
||||
LoadTwoPixels_SSE2(src, &cur_pixels);
|
||||
src += 4;
|
||||
while (1) {
|
||||
@ -75,11 +77,7 @@ static void RescalerImportRowExpand_SSE2(WebPRescaler* const wrk,
|
||||
} else {
|
||||
int left;
|
||||
const uint8_t* const src_limit = src + wrk->src_width - 8;
|
||||
if (wrk->src_width < 8) {
|
||||
WebPRescalerImportRowExpand_C(wrk, src);
|
||||
return;
|
||||
}
|
||||
LoadHeightPixels_SSE2(src, &cur_pixels);
|
||||
LoadEightPixels_SSE2(src, &cur_pixels);
|
||||
src += 7;
|
||||
left = 7;
|
||||
while (1) {
|
||||
@ -94,7 +92,7 @@ static void RescalerImportRowExpand_SSE2(WebPRescaler* const wrk,
|
||||
if (--left) {
|
||||
cur_pixels = _mm_srli_si128(cur_pixels, 2);
|
||||
} else if (src <= src_limit) {
|
||||
LoadHeightPixels_SSE2(src, &cur_pixels);
|
||||
LoadEightPixels_SSE2(src, &cur_pixels);
|
||||
src += 7;
|
||||
left = 7;
|
||||
} else { // tail
|
||||
|
@ -139,12 +139,7 @@ VP8AccumulateSSEFunc VP8AccumulateSSE;
|
||||
|
||||
extern void VP8SSIMDspInitSSE2(void);
|
||||
|
||||
static volatile VP8CPUInfo ssim_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&ssim_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8SSIMDspInit(void) {
|
||||
if (ssim_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8SSIMDspInit) {
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
VP8SSIMGetClipped = SSIMGetClipped_C;
|
||||
VP8SSIMGet = SSIMGet_C;
|
||||
@ -161,6 +156,4 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8SSIMDspInit(void) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ssim_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -219,12 +219,7 @@ extern void WebPInitYUV444ConvertersMIPSdspR2(void);
|
||||
extern void WebPInitYUV444ConvertersSSE2(void);
|
||||
extern void WebPInitYUV444ConvertersSSE41(void);
|
||||
|
||||
static volatile VP8CPUInfo upsampling_last_cpuinfo_used1 =
|
||||
(VP8CPUInfo)&upsampling_last_cpuinfo_used1;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444Converters(void) {
|
||||
if (upsampling_last_cpuinfo_used1 == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(WebPInitYUV444Converters) {
|
||||
WebPYUV444Converters[MODE_RGBA] = WebPYuv444ToRgba_C;
|
||||
WebPYUV444Converters[MODE_BGRA] = WebPYuv444ToBgra_C;
|
||||
WebPYUV444Converters[MODE_RGB] = WebPYuv444ToRgb_C;
|
||||
@ -254,7 +249,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitYUV444Converters(void) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
upsampling_last_cpuinfo_used1 = VP8GetCPUInfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -266,12 +260,7 @@ extern void WebPInitUpsamplersNEON(void);
|
||||
extern void WebPInitUpsamplersMIPSdspR2(void);
|
||||
extern void WebPInitUpsamplersMSA(void);
|
||||
|
||||
static volatile VP8CPUInfo upsampling_last_cpuinfo_used2 =
|
||||
(VP8CPUInfo)&upsampling_last_cpuinfo_used2;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplers(void) {
|
||||
if (upsampling_last_cpuinfo_used2 == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(WebPInitUpsamplers) {
|
||||
#ifdef FANCY_UPSAMPLING
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair_C;
|
||||
@ -333,7 +322,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitUpsamplers(void) {
|
||||
#endif
|
||||
|
||||
#endif // FANCY_UPSAMPLING
|
||||
upsampling_last_cpuinfo_used2 = VP8GetCPUInfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -75,12 +75,7 @@ extern void WebPInitSamplersSSE41(void);
|
||||
extern void WebPInitSamplersMIPS32(void);
|
||||
extern void WebPInitSamplersMIPSdspR2(void);
|
||||
|
||||
static volatile VP8CPUInfo yuv_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&yuv_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) {
|
||||
if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(WebPInitSamplers) {
|
||||
WebPSamplers[MODE_RGB] = YuvToRgbRow;
|
||||
WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
|
||||
WebPSamplers[MODE_BGR] = YuvToBgrRow;
|
||||
@ -116,7 +111,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) {
|
||||
}
|
||||
#endif // WEBP_USE_MIPS_DSP_R2
|
||||
}
|
||||
yuv_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -260,18 +254,13 @@ void (*WebPSharpYUVUpdateRGB)(const int16_t* ref, const int16_t* src,
|
||||
void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len,
|
||||
const uint16_t* best_y, uint16_t* out);
|
||||
|
||||
static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used;
|
||||
|
||||
extern void WebPInitConvertARGBToYUVSSE2(void);
|
||||
extern void WebPInitConvertARGBToYUVSSE41(void);
|
||||
extern void WebPInitConvertARGBToYUVNEON(void);
|
||||
extern void WebPInitSharpYUVSSE2(void);
|
||||
extern void WebPInitSharpYUVNEON(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) {
|
||||
if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(WebPInitConvertARGBToYUV) {
|
||||
WebPConvertARGBToY = ConvertARGBToY_C;
|
||||
WebPConvertARGBToUV = WebPConvertARGBToUV_C;
|
||||
|
||||
@ -316,6 +305,4 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) {
|
||||
assert(WebPSharpYUVUpdateY != NULL);
|
||||
assert(WebPSharpYUVUpdateRGB != NULL);
|
||||
assert(WebPSharpYUVFilterRow != NULL);
|
||||
|
||||
rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -1026,7 +1026,7 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(vikasa): Optimize HistogramRemap for low-effort compression mode also.
|
||||
// TODO(vrabaud): Optimize HistogramRemap for low-effort compression mode.
|
||||
// Find the optimal map from original histograms to the final ones.
|
||||
HistogramRemap(orig_histo, image_histo, histogram_symbols);
|
||||
|
||||
|
@ -146,6 +146,6 @@ int VP8ApplyNearLossless(const WebPPicture* const picture, int quality,
|
||||
|
||||
// Define a stub to suppress compiler warnings.
|
||||
extern void VP8LNearLosslessStub(void);
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8LNearLosslessStub(void) {}
|
||||
void VP8LNearLosslessStub(void) {}
|
||||
|
||||
#endif // (WEBP_NEAR_LOSSLESS == 1)
|
||||
|
@ -126,7 +126,7 @@ static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
|
||||
|
||||
#else
|
||||
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTables(void) {}
|
||||
static void InitGammaTables(void) {}
|
||||
static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return v; }
|
||||
static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
|
||||
return (int)(base_value << shift);
|
||||
@ -238,7 +238,7 @@ static WEBP_INLINE uint32_t LinearToGammaS(uint32_t value) {
|
||||
|
||||
#else
|
||||
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void InitGammaTablesS(void) {}
|
||||
static void InitGammaTablesS(void) {}
|
||||
static WEBP_INLINE uint32_t GammaToLinearS(int v) {
|
||||
return (v << GAMMA_TO_LINEAR_BITS) / MAX_Y_T;
|
||||
}
|
||||
|
@ -382,8 +382,7 @@ static int EncoderAnalyze(VP8LEncoder* const enc,
|
||||
AnalyzeAndCreatePalette(pic, low_effort,
|
||||
enc->palette_, &enc->palette_size_);
|
||||
|
||||
// TODO(jyrki): replace the decision to be based on an actual estimate
|
||||
// of entropy, or even spatial variance of entropy.
|
||||
// Empirical bit sizes.
|
||||
enc->histo_bits_ = GetHistoBits(method, use_palette,
|
||||
pic->width, pic->height);
|
||||
enc->transform_bits_ = GetTransformBits(method, enc->histo_bits_);
|
||||
@ -754,7 +753,6 @@ static WebPEncodingError StoreImageToBitMask(
|
||||
// Don't write the distance with the extra bits code since
|
||||
// the distance can be up to 18 bits of extra bits, and the prefix
|
||||
// 15 bits, totaling to 33, and our PutBits only supports up to 32 bits.
|
||||
// TODO(jyrki): optimize this further.
|
||||
VP8LPrefixEncode(distance, &code, &n_bits, &bits);
|
||||
WriteHuffmanCode(bw, codes + 4, code);
|
||||
VP8LPutBits(bw, bits, n_bits);
|
||||
@ -1876,7 +1874,6 @@ int VP8LEncodeImage(const WebPConfig* const config,
|
||||
err = VP8LEncodeStream(config, picture, &bw, 1 /*use_cache*/);
|
||||
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.
|
||||
|
@ -13,6 +13,8 @@ libwebpmuxinclude_HEADERS =
|
||||
libwebpmuxinclude_HEADERS += ../webp/mux.h
|
||||
libwebpmuxinclude_HEADERS += ../webp/mux_types.h
|
||||
libwebpmuxinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpmux_la_LIBADD = ../libwebp.la
|
||||
libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:2:0 -lm
|
||||
|
Reference in New Issue
Block a user