apply patches

This commit is contained in:
openKylinBot 2022-05-14 01:26:14 +08:00
commit 27c914d4fc
8 changed files with 115 additions and 23 deletions

View File

@ -9,6 +9,10 @@
// //
// WebP decode. // WebP decode.
#ifdef HAVE_CONFIG_H
#include "webp/config.h"
#endif
#include "./webpdec.h" #include "./webpdec.h"
#include <stdio.h> #include <stdio.h>
@ -162,7 +166,11 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
break; break;
} }
if (pic->use_argb) { if (pic->use_argb) {
#ifdef WORDS_BIGENDIAN
output_buffer->colorspace = MODE_ARGB;
#else
output_buffer->colorspace = MODE_BGRA; output_buffer->colorspace = MODE_BGRA;
#endif
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb; output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t); output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height; output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;

View File

@ -40,8 +40,8 @@ lossy or lossless compression for each frame heuristically. This global
option disables the local option \fB-lossy\fP and \fB-lossless\fP . option disables the local option \fB-lossy\fP and \fB-lossless\fP .
.TP .TP
.BI \-loop " int .BI \-loop " int
Specifies the number of times the animation should loop. Using '0' means Specifies the number of times the animation should loop. Using '0'
'loop indefinitely'. means 'loop indefinitely'.
.TP .TP
.BI \-v .BI \-v
Be more verbose. Be more verbose.

View File

@ -36,7 +36,7 @@ libwebp_la_LIBADD += utils/libwebputils.la
# other than the ones listed on the command line, i.e., after linking, it will # other than the ones listed on the command line, i.e., after linking, it will
# not have unresolved symbols. Some platforms (Windows among them) require all # not have unresolved symbols. Some platforms (Windows among them) require all
# symbols in shared libraries to be resolved at library creation. # symbols in shared libraries to be resolved at library creation.
libwebp_la_LDFLAGS = -no-undefined -version-info 7:1:0 libwebp_la_LDFLAGS = -no-undefined -version-info 6:2:0
libwebpincludedir = $(includedir)/webp libwebpincludedir = $(includedir)/webp
pkgconfig_DATA = libwebp.pc pkgconfig_DATA = libwebp.pc

View File

@ -366,6 +366,16 @@ static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b); return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
} }
#ifdef WORDS_BIGENDIAN
static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
const uint8_t* b, int len, uint32_t* out) {
int i;
for (i = 0; i < len; ++i) {
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
}
}
#endif
static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b, static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
int len, int step, uint32_t* out) { int len, int step, uint32_t* out) {
int i, offset = 0; int i, offset = 0;
@ -381,6 +391,10 @@ int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int); void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int); int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size); void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
#ifdef WORDS_BIGENDIAN
void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
const uint8_t* b, int, uint32_t*);
#endif
void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b, void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
int len, int step, uint32_t* out); int len, int step, uint32_t* out);
@ -405,6 +419,9 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
WebPMultRow = WebPMultRow_C; WebPMultRow = WebPMultRow_C;
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C; WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C;
#ifdef WORDS_BIGENDIAN
WebPPackARGB = PackARGB_C;
#endif
WebPPackRGB = PackRGB_C; WebPPackRGB = PackRGB_C;
#if !WEBP_NEON_OMIT_C_CODE #if !WEBP_NEON_OMIT_C_CODE
WebPApplyAlphaMultiply = ApplyAlphaMultiply_C; WebPApplyAlphaMultiply = ApplyAlphaMultiply_C;
@ -451,6 +468,9 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
assert(WebPDispatchAlphaToGreen != NULL); assert(WebPDispatchAlphaToGreen != NULL);
assert(WebPExtractAlpha != NULL); assert(WebPExtractAlpha != NULL);
assert(WebPExtractGreen != NULL); assert(WebPExtractGreen != NULL);
#ifdef WORDS_BIGENDIAN
assert(WebPPackARGB != NULL);
#endif
assert(WebPPackRGB != NULL); assert(WebPPackRGB != NULL);
assert(WebPHasAlpha8b != NULL); assert(WebPHasAlpha8b != NULL);
assert(WebPHasAlpha32b != NULL); assert(WebPHasAlpha32b != NULL);

View File

@ -125,6 +125,49 @@ static void MultARGBRow_MIPSdspR2(uint32_t* const ptr, int width,
} }
} }
#ifdef WORDS_BIGENDIAN
static void PackARGB_MIPSdspR2(const uint8_t* a, const uint8_t* r,
const uint8_t* g, const uint8_t* b, int len,
uint32_t* out) {
int temp0, temp1, temp2, temp3, offset;
const int rest = len & 1;
const uint32_t* const loop_end = out + len - rest;
const int step = 4;
__asm__ volatile (
"xor %[offset], %[offset], %[offset] \n\t"
"beq %[loop_end], %[out], 0f \n\t"
"2: \n\t"
"lbux %[temp0], %[offset](%[a]) \n\t"
"lbux %[temp1], %[offset](%[r]) \n\t"
"lbux %[temp2], %[offset](%[g]) \n\t"
"lbux %[temp3], %[offset](%[b]) \n\t"
"ins %[temp1], %[temp0], 16, 16 \n\t"
"ins %[temp3], %[temp2], 16, 16 \n\t"
"addiu %[out], %[out], 4 \n\t"
"precr.qb.ph %[temp0], %[temp1], %[temp3] \n\t"
"sw %[temp0], -4(%[out]) \n\t"
"addu %[offset], %[offset], %[step] \n\t"
"bne %[loop_end], %[out], 2b \n\t"
"0: \n\t"
"beq %[rest], $zero, 1f \n\t"
"lbux %[temp0], %[offset](%[a]) \n\t"
"lbux %[temp1], %[offset](%[r]) \n\t"
"lbux %[temp2], %[offset](%[g]) \n\t"
"lbux %[temp3], %[offset](%[b]) \n\t"
"ins %[temp1], %[temp0], 16, 16 \n\t"
"ins %[temp3], %[temp2], 16, 16 \n\t"
"precr.qb.ph %[temp0], %[temp1], %[temp3] \n\t"
"sw %[temp0], 0(%[out]) \n\t"
"1: \n\t"
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
[temp3]"=&r"(temp3), [offset]"=&r"(offset), [out]"+&r"(out)
: [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
[loop_end]"r"(loop_end), [rest]"r"(rest)
: "memory"
);
}
#endif // WORDS_BIGENDIAN
static void PackRGB_MIPSdspR2(const uint8_t* r, const uint8_t* g, static void PackRGB_MIPSdspR2(const uint8_t* r, const uint8_t* g,
const uint8_t* b, int len, int step, const uint8_t* b, int len, int step,
uint32_t* out) { uint32_t* out) {
@ -172,6 +215,9 @@ extern void WebPInitAlphaProcessingMIPSdspR2(void);
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) { WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) {
WebPDispatchAlpha = DispatchAlpha_MIPSdspR2; WebPDispatchAlpha = DispatchAlpha_MIPSdspR2;
WebPMultARGBRow = MultARGBRow_MIPSdspR2; WebPMultARGBRow = MultARGBRow_MIPSdspR2;
#ifdef WORDS_BIGENDIAN
WebPPackARGB = PackARGB_MIPSdspR2;
#endif
WebPPackRGB = PackRGB_MIPSdspR2; WebPPackRGB = PackRGB_MIPSdspR2;
} }

View File

@ -166,6 +166,13 @@ extern "C" {
#define WEBP_SWAP_16BIT_CSP 0 #define WEBP_SWAP_16BIT_CSP 0
#endif #endif
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
#if !defined(WORDS_BIGENDIAN) && \
(defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
#define WORDS_BIGENDIAN
#endif
typedef enum { typedef enum {
kSSE2, kSSE2,
kSSE3, kSSE3,
@ -578,6 +585,13 @@ void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
int width, int inverse); int width, int inverse);
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse); void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
#ifdef WORDS_BIGENDIAN
// ARGB packing function: a/r/g/b input is rgba or bgra order.
extern void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r,
const uint8_t* g, const uint8_t* b, int len,
uint32_t* out);
#endif
// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order. // RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b, extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
int len, int step, uint32_t* out); int len, int step, uint32_t* out);

View File

@ -28,11 +28,11 @@
// If defined, use table to compute x / alpha. // If defined, use table to compute x / alpha.
#define USE_INVERSE_ALPHA_TABLE #define USE_INVERSE_ALPHA_TABLE
static const union { #ifdef WORDS_BIGENDIAN
uint32_t argb; #define ALPHA_OFFSET 0 // uint32_t 0xff000000 is 0xff,00,00,00 in memory
uint8_t bytes[4]; #else
} test_endian = { 0xff000000u }; #define ALPHA_OFFSET 3 // uint32_t 0xff000000 is 0x00,00,00,ff in memory
#define ALPHA_IS_LAST (test_endian.bytes[3] == 0xff) #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Detection of non-trivial transparency // Detection of non-trivial transparency
@ -61,7 +61,7 @@ int WebPPictureHasTransparency(const WebPPicture* picture) {
return CheckNonOpaque(picture->a, picture->width, picture->height, return CheckNonOpaque(picture->a, picture->width, picture->height,
1, picture->a_stride); 1, picture->a_stride);
} else { } else {
const int alpha_offset = ALPHA_IS_LAST ? 3 : 0; const int alpha_offset = ALPHA_OFFSET;
return CheckNonOpaque((const uint8_t*)picture->argb + alpha_offset, return CheckNonOpaque((const uint8_t*)picture->argb + alpha_offset,
picture->width, picture->height, picture->width, picture->height,
4, picture->argb_stride * sizeof(*picture->argb)); 4, picture->argb_stride * sizeof(*picture->argb));
@ -990,10 +990,10 @@ static int PictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace,
return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION); return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
} else { } else {
const uint8_t* const argb = (const uint8_t*)picture->argb; const uint8_t* const argb = (const uint8_t*)picture->argb;
const uint8_t* const r = ALPHA_IS_LAST ? argb + 2 : argb + 1; const uint8_t* const a = argb + (0 ^ ALPHA_OFFSET);
const uint8_t* const g = ALPHA_IS_LAST ? argb + 1 : argb + 2; const uint8_t* const r = argb + (1 ^ ALPHA_OFFSET);
const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3; const uint8_t* const g = argb + (2 ^ ALPHA_OFFSET);
const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0; const uint8_t* const b = argb + (3 ^ ALPHA_OFFSET);
picture->colorspace = WEBP_YUV420; picture->colorspace = WEBP_YUV420;
return ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, return ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride,
@ -1044,7 +1044,8 @@ int WebPPictureYUVAToARGB(WebPPicture* picture) {
const int argb_stride = 4 * picture->argb_stride; const int argb_stride = 4 * picture->argb_stride;
uint8_t* dst = (uint8_t*)picture->argb; uint8_t* dst = (uint8_t*)picture->argb;
const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y; const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST); WebPUpsampleLinePairFunc upsample =
WebPGetLinePairConverter(ALPHA_OFFSET > 0);
// First row, with replicated top samples. // First row, with replicated top samples.
upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width); upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
@ -1087,6 +1088,7 @@ static int Import(WebPPicture* const picture,
const uint8_t* rgb, int rgb_stride, const uint8_t* rgb, int rgb_stride,
int step, int swap_rb, int import_alpha) { int step, int swap_rb, int import_alpha) {
int y; int y;
// swap_rb -> b,g,r,a , !swap_rb -> r,g,b,a
const uint8_t* r_ptr = rgb + (swap_rb ? 2 : 0); const uint8_t* r_ptr = rgb + (swap_rb ? 2 : 0);
const uint8_t* g_ptr = rgb + 1; const uint8_t* g_ptr = rgb + 1;
const uint8_t* b_ptr = rgb + (swap_rb ? 0 : 2); const uint8_t* b_ptr = rgb + (swap_rb ? 0 : 2);
@ -1104,16 +1106,25 @@ static int Import(WebPPicture* const picture,
WebPInitAlphaProcessing(); WebPInitAlphaProcessing();
if (import_alpha) { if (import_alpha) {
// dst[] byte order is {a,r,g,b} for big-endian, {b,g,r,a} for little endian
uint32_t* dst = picture->argb; uint32_t* dst = picture->argb;
const int do_copy = const int do_copy = (ALPHA_OFFSET == 3) && swap_rb;
(!swap_rb && !ALPHA_IS_LAST) || (swap_rb && ALPHA_IS_LAST);
assert(step == 4); assert(step == 4);
for (y = 0; y < height; ++y) { for (y = 0; y < height; ++y) {
if (do_copy) { if (do_copy) {
memcpy(dst, rgb, width * 4); memcpy(dst, rgb, width * 4);
} else { } else {
#ifdef WORDS_BIGENDIAN
// BGRA or RGBA input order.
const uint8_t* a_ptr = rgb + 3;
WebPPackARGB(a_ptr, r_ptr, g_ptr, b_ptr, width, dst);
r_ptr += rgb_stride;
g_ptr += rgb_stride;
b_ptr += rgb_stride;
#else
// RGBA input order. Need to swap R and B. // RGBA input order. Need to swap R and B.
VP8LConvertBGRAToRGBA((const uint32_t*)rgb, width, (uint8_t*)dst); VP8LConvertBGRAToRGBA((const uint32_t*)rgb, width, (uint8_t*)dst);
#endif
} }
rgb += rgb_stride; rgb += rgb_stride;
dst += picture->argb_stride; dst += picture->argb_stride;

View File

@ -19,13 +19,6 @@
#include "src/dsp/dsp.h" #include "src/dsp/dsp.h"
#include "src/webp/types.h" #include "src/webp/types.h"
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
#if !defined(WORDS_BIGENDIAN) && \
(defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
#define WORDS_BIGENDIAN
#endif
#if defined(WORDS_BIGENDIAN) #if defined(WORDS_BIGENDIAN)
#define HToLE32 BSwap32 #define HToLE32 BSwap32
#define HToLE16 BSwap16 #define HToLE16 BSwap16