From 1b75e53be8d1aae6c14af57d43d7dcdc1d995c74 Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Tue, 27 Feb 2018 11:32:23 +0100 Subject: [PATCH] More big-endian fixes --- 3005237.patch | 35 ----- d51d03e.patch | 96 ------------- libwebp.spec | 8 +- libwebp_big-endian.patch | 287 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+), 134 deletions(-) delete mode 100644 3005237.patch delete mode 100644 d51d03e.patch create mode 100644 libwebp_big-endian.patch diff --git a/3005237.patch b/3005237.patch deleted file mode 100644 index d9a5f05..0000000 --- a/3005237.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3005237a5d68d1e1f465d925040a9507f55e8895 Mon Sep 17 00:00:00 2001 -From: Pascal Massimino -Date: Wed, 14 Feb 2018 23:23:51 -0800 -Subject: [PATCH] ReadWebP: fix for big-endian - -Change-Id: I36b3c12ccf02eb5dad350c460387c0528fff8df3 ---- - -diff --git a/imageio/webpdec.c b/imageio/webpdec.c -index 15d87ea..82f646d 100644 ---- a/imageio/webpdec.c -+++ b/imageio/webpdec.c -@@ -9,6 +9,10 @@ - // - // WebP decode. - -+#ifdef HAVE_CONFIG_H -+#include "webp/config.h" -+#endif -+ - #include "./webpdec.h" - - #include -@@ -150,7 +154,11 @@ - break; - } - if (pic->use_argb) { -+#ifdef WORDS_BIGENDIAN -+ output_buffer->colorspace = MODE_ARGB; -+#else - output_buffer->colorspace = MODE_BGRA; -+#endif - output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb; - output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t); - output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height; diff --git a/d51d03e.patch b/d51d03e.patch deleted file mode 100644 index c23efdf..0000000 --- a/d51d03e.patch +++ /dev/null @@ -1,96 +0,0 @@ -From d51d03edd54d01aee638ac6f294c2ae105ff2929 Mon Sep 17 00:00:00 2001 -From: Pascal Massimino -Date: Thu, 15 Feb 2018 21:44:39 -0800 -Subject: [PATCH] fix for BigEndian import - -+ simplification of the logic - -Change-Id: Ia20ce844793ed35ea03a17cef45838f3d0ae4afa ---- - -diff --git a/src/enc/picture_csp_enc.c b/src/enc/picture_csp_enc.c -index d531dd0..7444094 100644 ---- a/src/enc/picture_csp_enc.c -+++ b/src/enc/picture_csp_enc.c -@@ -11,6 +11,10 @@ - // - // Author: Skal (pascal.massimino@gmail.com) - -+#ifdef HAVE_CONFIG_H -+#include "src/webp/config.h" -+#endif -+ - #include - #include - #include -@@ -28,11 +32,11 @@ - // If defined, use table to compute x / alpha. - #define USE_INVERSE_ALPHA_TABLE - --static const union { -- uint32_t argb; -- uint8_t bytes[4]; --} test_endian = { 0xff000000u }; --#define ALPHA_IS_LAST (test_endian.bytes[3] == 0xff) -+#ifdef WORDS_BIGENDIAN -+#define ALPHA_OFFSET 0 // uint32_t 0xff000000 is 0xff,00,00,00 in memory -+#else -+#define ALPHA_OFFSET 3 // uint32_t 0xff000000 is 0x00,00,00,ff in memory -+#endif - - //------------------------------------------------------------------------------ - // Detection of non-trivial transparency -@@ -61,7 +65,7 @@ - return CheckNonOpaque(picture->a, picture->width, picture->height, - 1, picture->a_stride); - } 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, - picture->width, picture->height, - 4, picture->argb_stride * sizeof(*picture->argb)); -@@ -990,10 +994,10 @@ - return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION); - } else { - 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 g = ALPHA_IS_LAST ? argb + 1 : argb + 2; -- const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3; -- const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0; -+ const uint8_t* const a = argb + (0 ^ ALPHA_OFFSET); -+ const uint8_t* const r = argb + (1 ^ ALPHA_OFFSET); -+ const uint8_t* const g = argb + (2 ^ ALPHA_OFFSET); -+ const uint8_t* const b = argb + (3 ^ ALPHA_OFFSET); - - picture->colorspace = WEBP_YUV420; - return ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, -@@ -1044,7 +1048,8 @@ - const int argb_stride = 4 * picture->argb_stride; - uint8_t* dst = (uint8_t*)picture->argb; - 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. - upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width); -@@ -1087,6 +1092,7 @@ - const uint8_t* rgb, int rgb_stride, - int step, int swap_rb, int import_alpha) { - 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* g_ptr = rgb + 1; - const uint8_t* b_ptr = rgb + (swap_rb ? 0 : 2); -@@ -1104,9 +1110,9 @@ - WebPInitAlphaProcessing(); - - 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; -- const int do_copy = -- (!swap_rb && !ALPHA_IS_LAST) || (swap_rb && ALPHA_IS_LAST); -+ const int do_copy = (ALPHA_OFFSET == 3) && swap_rb; - assert(step == 4); - for (y = 0; y < height; ++y) { - if (do_copy) { diff --git a/libwebp.spec b/libwebp.spec index 308582a..ae965c9 100644 --- a/libwebp.spec +++ b/libwebp.spec @@ -2,7 +2,7 @@ Name: libwebp Version: 0.6.1 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://webmproject.org/ Summary: Library and tools for the WebP graphics format # Additional IPR is licensed as well. See PATENTS file for details @@ -10,8 +10,7 @@ License: BSD Source0: http://downloads.webmproject.org/releases/webp/%{name}-%{version}.tar.gz Source1: libwebp_jni_example.java # Backport upstream big-endian fixes -Patch0: 3005237.patch -Patch1: d51d03e.patch +Patch0: libwebp_big-endian.patch BuildRequires: libjpeg-devel BuildRequires: libpng-devel @@ -143,6 +142,9 @@ cp swig/*.jar swig/*.so %{buildroot}/%{_libdir}/%{name}-java/ %changelog +* Mon Feb 26 2018 Sandro Mani - 0.6.1-7 +- More big-endian fixes + * Fri Feb 16 2018 Sandro Mani - 0.6.1-6 - Backport another big-endian fix diff --git a/libwebp_big-endian.patch b/libwebp_big-endian.patch new file mode 100644 index 0000000..ac73a53 --- /dev/null +++ b/libwebp_big-endian.patch @@ -0,0 +1,287 @@ +Description: big endian fixes + Webp 0.6.1 was totally busted on big endian machines. Backporting + the fixes, which will be part of 0.6.2. Close coordination with + upstream for this. + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: upstream +Forwarded: yes +Reviewed-By: James Zern, Jeff Breidenbach +Last-Update: 2018-02-23 + +--- libwebp-0.6.1.orig/imageio/webpdec.c ++++ libwebp-0.6.1/imageio/webpdec.c +@@ -9,6 +9,10 @@ + // + // WebP decode. + ++#ifdef HAVE_CONFIG_H ++#include "webp/config.h" ++#endif ++ + #include "./webpdec.h" + + #include +@@ -162,7 +166,11 @@ int ReadWebP(const uint8_t* const data, + break; + } + if (pic->use_argb) { ++#ifdef WORDS_BIGENDIAN ++ output_buffer->colorspace = MODE_ARGB; ++#else + output_buffer->colorspace = MODE_BGRA; ++#endif + output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb; + output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t); + output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height; +--- libwebp-0.6.1.orig/src/dsp/alpha_processing.c ++++ libwebp-0.6.1/src/dsp/alpha_processing.c +@@ -366,6 +366,16 @@ static WEBP_INLINE uint32_t MakeARGB32(i + 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, + int len, int step, uint32_t* out) { + int i, offset = 0; +@@ -381,6 +391,10 @@ int (*WebPDispatchAlpha)(const uint8_t*, + void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int); + int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int); + 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, + int len, int step, uint32_t* out); + +@@ -405,6 +419,9 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitA + WebPMultRow = WebPMultRow_C; + WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C; + ++#ifdef WORDS_BIGENDIAN ++ WebPPackARGB = PackARGB_C; ++#endif + WebPPackRGB = PackRGB_C; + #if !WEBP_NEON_OMIT_C_CODE + WebPApplyAlphaMultiply = ApplyAlphaMultiply_C; +@@ -451,6 +468,9 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitA + assert(WebPDispatchAlphaToGreen != NULL); + assert(WebPExtractAlpha != NULL); + assert(WebPExtractGreen != NULL); ++#ifdef WORDS_BIGENDIAN ++ assert(WebPPackARGB != NULL); ++#endif + assert(WebPPackRGB != NULL); + assert(WebPHasAlpha8b != NULL); + assert(WebPHasAlpha32b != NULL); +--- libwebp-0.6.1.orig/src/dsp/alpha_processing_mips_dsp_r2.c ++++ libwebp-0.6.1/src/dsp/alpha_processing_mips_dsp_r2.c +@@ -125,6 +125,49 @@ static void MultARGBRow_MIPSdspR2(uint32 + } + } + ++#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, + const uint8_t* b, int len, int step, + uint32_t* out) { +@@ -172,6 +215,9 @@ extern void WebPInitAlphaProcessingMIPSd + WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) { + WebPDispatchAlpha = DispatchAlpha_MIPSdspR2; + WebPMultARGBRow = MultARGBRow_MIPSdspR2; ++#ifdef WORDS_BIGENDIAN ++ WebPPackARGB = PackARGB_MIPSdspR2; ++#endif + WebPPackRGB = PackRGB_MIPSdspR2; + } + +--- libwebp-0.6.1.orig/src/dsp/dsp.h ++++ libwebp-0.6.1/src/dsp/dsp.h +@@ -166,6 +166,13 @@ extern "C" { + #define WEBP_SWAP_16BIT_CSP 0 + #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 { + kSSE2, + kSSE3, +@@ -578,6 +585,13 @@ void WebPMultRow_C(uint8_t* const ptr, c + 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. + extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b, + int len, int step, uint32_t* out); +--- libwebp-0.6.1.orig/src/enc/picture_csp_enc.c ++++ libwebp-0.6.1/src/enc/picture_csp_enc.c +@@ -28,11 +28,11 @@ + // If defined, use table to compute x / alpha. + #define USE_INVERSE_ALPHA_TABLE + +-static const union { +- uint32_t argb; +- uint8_t bytes[4]; +-} test_endian = { 0xff000000u }; +-#define ALPHA_IS_LAST (test_endian.bytes[3] == 0xff) ++#ifdef WORDS_BIGENDIAN ++#define ALPHA_OFFSET 0 // uint32_t 0xff000000 is 0xff,00,00,00 in memory ++#else ++#define ALPHA_OFFSET 3 // uint32_t 0xff000000 is 0x00,00,00,ff in memory ++#endif + + //------------------------------------------------------------------------------ + // Detection of non-trivial transparency +@@ -61,7 +61,7 @@ int WebPPictureHasTransparency(const Web + return CheckNonOpaque(picture->a, picture->width, picture->height, + 1, picture->a_stride); + } 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, + picture->width, picture->height, + 4, picture->argb_stride * sizeof(*picture->argb)); +@@ -990,10 +990,10 @@ static int PictureARGBToYUVA(WebPPicture + return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION); + } else { + 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 g = ALPHA_IS_LAST ? argb + 1 : argb + 2; +- const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3; +- const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0; ++ const uint8_t* const a = argb + (0 ^ ALPHA_OFFSET); ++ const uint8_t* const r = argb + (1 ^ ALPHA_OFFSET); ++ const uint8_t* const g = argb + (2 ^ ALPHA_OFFSET); ++ const uint8_t* const b = argb + (3 ^ ALPHA_OFFSET); + + picture->colorspace = WEBP_YUV420; + return ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, +@@ -1044,7 +1044,8 @@ int WebPPictureYUVAToARGB(WebPPicture* p + const int argb_stride = 4 * picture->argb_stride; + uint8_t* dst = (uint8_t*)picture->argb; + 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. + upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width); +@@ -1087,6 +1088,7 @@ static int Import(WebPPicture* const pic + const uint8_t* rgb, int rgb_stride, + int step, int swap_rb, int import_alpha) { + 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* g_ptr = rgb + 1; + const uint8_t* b_ptr = rgb + (swap_rb ? 0 : 2); +@@ -1104,16 +1106,25 @@ static int Import(WebPPicture* const pic + WebPInitAlphaProcessing(); + + 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; +- const int do_copy = +- (!swap_rb && !ALPHA_IS_LAST) || (swap_rb && ALPHA_IS_LAST); ++ const int do_copy = (ALPHA_OFFSET == 3) && swap_rb; + assert(step == 4); + for (y = 0; y < height; ++y) { + if (do_copy) { + memcpy(dst, rgb, width * 4); + } 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. + VP8LConvertBGRAToRGBA((const uint32_t*)rgb, width, (uint8_t*)dst); ++#endif + } + rgb += rgb_stride; + dst += picture->argb_stride; +--- libwebp-0.6.1.orig/src/utils/endian_inl_utils.h ++++ libwebp-0.6.1/src/utils/endian_inl_utils.h +@@ -19,13 +19,6 @@ + #include "src/dsp/dsp.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) + #define HToLE32 BSwap32 + #define HToLE16 BSwap16