--- modules/skcms/src/Transform_inl.h.orig
+++ modules/skcms/src/Transform_inl.h
@@ -494,7 +494,9 @@
 
 SI U32 gather_24(const uint8_t* p, I32 ix) {
     // First, back up a byte.  Any place we're gathering from has a safe junk byte to read
-    // in front of it, either a previous table value, or some tag metadata.
+    // in front of it, either a previous table value, or some tag metadata.  (There is no
+    // such guarantee *after* the table, so big-endian must read the same bytes and mask,
+    // rather than reading one byte further along.)
     p -= 1;
 
     // Load the i'th 24-bit value from p, and 1 extra byte.
@@ -530,8 +532,14 @@
     U32 v = (U32)_mm512_i32gather_epi32((__m512i)(3*ix), p4, 1);
 #endif
 
-    // Shift off the junk byte, leaving r,g,b in low 24 bits (and zero in the top 8).
+    // Drop the junk byte, leaving r,g,b in the low 24 bits (and zero in the top 8).
+    // Little-endian loaded [junk,r,g,b] as b<<24|g<<16|r<<8|junk, big-endian as
+    // junk<<24|r<<16|g<<8|b, so the junk byte is at the opposite end.
+#if defined(SKCMS_BIG_ENDIAN)
+    return v & 0x00ffffff;
+#else
     return v >> 8;
+#endif
 }
 
 #if !defined(__arm__)
@@ -589,7 +597,11 @@
         store((char*)v + 64, hi);
     #endif
 
+#if defined(SKCMS_BIG_ENDIAN)
+        *v &= 0x0000ffffffffffffULL;
+#else
         *v >>= 16;
+#endif
     }
 #endif
 
@@ -600,9 +612,13 @@
 SI F F_from_U16_BE(U16 v) {
     // All 16-bit ICC values are big-endian, so we byte swap before converting to float.
     // MSVC catches the "loss" of data here in the portable path, so we also make sure to mask.
+#if !defined(SKCMS_BIG_ENDIAN)
     U16 lo = (v >> 8),
         hi = (v << 8) & 0xffff;
     return cast<F>(lo|hi) * (1/65535.0f);
+#else
+    return cast<F>(v) * (1/65535.0f);
+#endif
 }
 
 SI U16 U16_from_F(F v) {
@@ -641,19 +657,32 @@
 SI void sample_clut_8(const uint8_t* grid_8, I32 ix, F* r, F* g, F* b) {
     U32 rgb = gather_24(grid_8, ix);
 
+#if defined(SKCMS_BIG_ENDIAN)
+    *r = cast<F>((rgb >> 16) & 0xff) * (1/255.0f);
+    *g = cast<F>((rgb >>  8) & 0xff) * (1/255.0f);
+    *b = cast<F>((rgb >>  0) & 0xff) * (1/255.0f);
+#else
     *r = cast<F>((rgb >>  0) & 0xff) * (1/255.0f);
     *g = cast<F>((rgb >>  8) & 0xff) * (1/255.0f);
     *b = cast<F>((rgb >> 16) & 0xff) * (1/255.0f);
+#endif
 }
 
 SI void sample_clut_8(const uint8_t* grid_8, I32 ix, F* r, F* g, F* b, F* a) {
     // TODO: don't forget to optimize gather_32().
     U32 rgba = gather_32(grid_8, ix);
 
+#if defined(SKCMS_BIG_ENDIAN)
+    *r = cast<F>((rgba >> 24) & 0xff) * (1/255.0f);
+    *g = cast<F>((rgba >> 16) & 0xff) * (1/255.0f);
+    *b = cast<F>((rgba >>  8) & 0xff) * (1/255.0f);
+    *a = cast<F>((rgba >>  0) & 0xff) * (1/255.0f);
+#else
     *r = cast<F>((rgba >>  0) & 0xff) * (1/255.0f);
     *g = cast<F>((rgba >>  8) & 0xff) * (1/255.0f);
     *b = cast<F>((rgba >> 16) & 0xff) * (1/255.0f);
     *a = cast<F>((rgba >> 24) & 0xff) * (1/255.0f);
+#endif
 }
 
 SI void sample_clut_16(const uint8_t* grid_16, I32 ix, F* r, F* g, F* b) {
@@ -666,12 +695,18 @@
     // This strategy is much faster for 64-bit builds, and fine for 32-bit x86 too.
     U64 rgb;
     gather_48(grid_16, ix, &rgb);
+#if defined(SKCMS_BIG_ENDIAN)
+    *r = cast<F>((rgb >> 32) & 0xffff) * (1/65535.0f);
+    *g = cast<F>((rgb >> 16) & 0xffff) * (1/65535.0f);
+    *b = cast<F>((rgb >>  0) & 0xffff) * (1/65535.0f);
+#else
     rgb = swap_endian_16x4(rgb);
 
     *r = cast<F>((rgb >>  0) & 0xffff) * (1/65535.0f);
     *g = cast<F>((rgb >> 16) & 0xffff) * (1/65535.0f);
     *b = cast<F>((rgb >> 32) & 0xffff) * (1/65535.0f);
 #endif
+#endif
 }
 
 SI void sample_clut_16(const uint8_t* grid_16, I32 ix, F* r, F* g, F* b, F* a) {
@@ -896,10 +931,17 @@
 STAGE(load_8888, NoCtx) {
     U32 rgba = load<U32>(src + 4*i);
 
+#if defined(SKCMS_BIG_ENDIAN)
+    r = cast<F>((rgba >> 24) & 0xff) * (1/255.0f);
+    g = cast<F>((rgba >> 16) & 0xff) * (1/255.0f);
+    b = cast<F>((rgba >>  8) & 0xff) * (1/255.0f);
+    a = cast<F>((rgba >>  0) & 0xff) * (1/255.0f);
+#else
     r = cast<F>((rgba >>  0) & 0xff) * (1/255.0f);
     g = cast<F>((rgba >>  8) & 0xff) * (1/255.0f);
     b = cast<F>((rgba >> 16) & 0xff) * (1/255.0f);
     a = cast<F>((rgba >> 24) & 0xff) * (1/255.0f);
+#endif
 }
 
 STAGE(load_1010102, NoCtx) {
@@ -933,14 +975,30 @@
     const uint16_t* rgb = (const uint16_t*)ptr; // cast to const uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x3_t v = vld3_u16(rgb);
+#if defined(SKCMS_BIG_ENDIAN)
+    r = cast<F>(swap_endian_16((U16)v.val[0])) * (1/65535.0f);
+    g = cast<F>(swap_endian_16((U16)v.val[1])) * (1/65535.0f);
+    b = cast<F>(swap_endian_16((U16)v.val[2])) * (1/65535.0f);
+#else
     r = cast<F>((U16)v.val[0]) * (1/65535.0f);
     g = cast<F>((U16)v.val[1]) * (1/65535.0f);
     b = cast<F>((U16)v.val[2]) * (1/65535.0f);
+#endif
+#else
+#if defined(SKCMS_BIG_ENDIAN)
+    U32 R = load_3<U32>(rgb+0),
+        G = load_3<U32>(rgb+1),
+        B = load_3<U32>(rgb+2);
+    // R,G,B are little-endian 16-bit, so byte swap them before converting to float.
+    r = cast<F>((R & 0x00ff)<<8 | (R & 0xff00)>>8) * (1/65535.0f);
+    g = cast<F>((G & 0x00ff)<<8 | (G & 0xff00)>>8) * (1/65535.0f);
+    b = cast<F>((B & 0x00ff)<<8 | (B & 0xff00)>>8) * (1/65535.0f);
 #else
     r = cast<F>(load_3<U32>(rgb+0)) * (1/65535.0f);
     g = cast<F>(load_3<U32>(rgb+1)) * (1/65535.0f);
     b = cast<F>(load_3<U32>(rgb+2)) * (1/65535.0f);
 #endif
+#endif
 }
 
 STAGE(load_16161616LE, NoCtx) {
@@ -949,10 +1007,25 @@
     const uint16_t* rgba = (const uint16_t*)ptr; // cast to const uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x4_t v = vld4_u16(rgba);
+#if defined(SKCMS_BIG_ENDIAN)
+    r = cast<F>(swap_endian_16((U16)v.val[0])) * (1/65535.0f);
+    g = cast<F>(swap_endian_16((U16)v.val[1])) * (1/65535.0f);
+    b = cast<F>(swap_endian_16((U16)v.val[2])) * (1/65535.0f);
+    a = cast<F>(swap_endian_16((U16)v.val[3])) * (1/65535.0f);
+#else
     r = cast<F>((U16)v.val[0]) * (1/65535.0f);
     g = cast<F>((U16)v.val[1]) * (1/65535.0f);
     b = cast<F>((U16)v.val[2]) * (1/65535.0f);
     a = cast<F>((U16)v.val[3]) * (1/65535.0f);
+#endif
+#else
+#if defined(SKCMS_BIG_ENDIAN)
+    U64 px = swap_endian_16x4(load<U64>(rgba));
+
+    r = cast<F>((px >> 48) & 0xffff) * (1/65535.0f);
+    g = cast<F>((px >> 32) & 0xffff) * (1/65535.0f);
+    b = cast<F>((px >> 16) & 0xffff) * (1/65535.0f);
+    a = cast<F>((px >>  0) & 0xffff) * (1/65535.0f);
 #else
     U64 px = load<U64>(rgba);
 
@@ -961,6 +1034,7 @@
     b = cast<F>((px >> 32) & 0xffff) * (1/65535.0f);
     a = cast<F>((px >> 48) & 0xffff) * (1/65535.0f);
 #endif
+#endif
 }
 
 STAGE(load_161616BE, NoCtx) {
@@ -969,9 +1043,20 @@
     const uint16_t* rgb = (const uint16_t*)ptr; // cast to const uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x3_t v = vld3_u16(rgb);
+#if defined(SKCMS_BIG_ENDIAN)
+    r = cast<F>((U16)v.val[0]) * (1/65535.0f);
+    g = cast<F>((U16)v.val[1]) * (1/65535.0f);
+    b = cast<F>((U16)v.val[2]) * (1/65535.0f);
+#else
     r = cast<F>(swap_endian_16((U16)v.val[0])) * (1/65535.0f);
     g = cast<F>(swap_endian_16((U16)v.val[1])) * (1/65535.0f);
     b = cast<F>(swap_endian_16((U16)v.val[2])) * (1/65535.0f);
+#endif
+#else
+#if defined(SKCMS_BIG_ENDIAN)
+    r = cast<F>(load_3<U32>(rgb+0)) * (1/65535.0f);
+    g = cast<F>(load_3<U32>(rgb+1)) * (1/65535.0f);
+    b = cast<F>(load_3<U32>(rgb+2)) * (1/65535.0f);
 #else
     U32 R = load_3<U32>(rgb+0),
         G = load_3<U32>(rgb+1),
@@ -981,6 +1066,7 @@
     g = cast<F>((G & 0x00ff)<<8 | (G & 0xff00)>>8) * (1/65535.0f);
     b = cast<F>((B & 0x00ff)<<8 | (B & 0xff00)>>8) * (1/65535.0f);
 #endif
+#endif
 }
 
 STAGE(load_16161616BE, NoCtx) {
@@ -989,10 +1075,25 @@
     const uint16_t* rgba = (const uint16_t*)ptr; // cast to const uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x4_t v = vld4_u16(rgba);
+#if defined(SKCMS_BIG_ENDIAN)
+    r = cast<F>((U16)v.val[0]) * (1/65535.0f);
+    g = cast<F>((U16)v.val[1]) * (1/65535.0f);
+    b = cast<F>((U16)v.val[2]) * (1/65535.0f);
+    a = cast<F>((U16)v.val[3]) * (1/65535.0f);
+#else
     r = cast<F>(swap_endian_16((U16)v.val[0])) * (1/65535.0f);
     g = cast<F>(swap_endian_16((U16)v.val[1])) * (1/65535.0f);
     b = cast<F>(swap_endian_16((U16)v.val[2])) * (1/65535.0f);
     a = cast<F>(swap_endian_16((U16)v.val[3])) * (1/65535.0f);
+#endif
+#else
+#if defined(SKCMS_BIG_ENDIAN)
+    U64 px = load<U64>(rgba);
+
+    r = cast<F>((px >> 48) & 0xffff) * (1/65535.0f);
+    g = cast<F>((px >> 32) & 0xffff) * (1/65535.0f);
+    b = cast<F>((px >> 16) & 0xffff) * (1/65535.0f);
+    a = cast<F>((px >>  0) & 0xffff) * (1/65535.0f);
 #else
     U64 px = swap_endian_16x4(load<U64>(rgba));
 
@@ -1001,6 +1102,7 @@
     b = cast<F>((px >> 32) & 0xffff) * (1/65535.0f);
     a = cast<F>((px >> 48) & 0xffff) * (1/65535.0f);
 #endif
+#endif
 }
 
 STAGE(load_hhh, NoCtx) {
@@ -1034,11 +1136,18 @@
         A = (U16)v.val[3];
 #else
     U64 px = load<U64>(rgba);
+#if defined(SKCMS_BIG_ENDIAN)
+    U16 R = cast<U16>((px >> 48) & 0xffff),
+        G = cast<U16>((px >> 32) & 0xffff),
+        B = cast<U16>((px >> 16) & 0xffff),
+        A = cast<U16>((px >>  0) & 0xffff);
+#else
     U16 R = cast<U16>((px >>  0) & 0xffff),
         G = cast<U16>((px >> 16) & 0xffff),
         B = cast<U16>((px >> 32) & 0xffff),
         A = cast<U16>((px >> 48) & 0xffff);
 #endif
+#endif
     r = F_from_Half(R);
     g = F_from_Half(G);
     b = F_from_Half(B);
@@ -1344,10 +1453,17 @@
 }
 
 FINAL_STAGE(store_8888, NoCtx) {
+#if defined(SKCMS_BIG_ENDIAN)
+    store(dst + 4*i, cast<U32>(to_fixed(r * 255)) << 24
+                   | cast<U32>(to_fixed(g * 255)) << 16
+                   | cast<U32>(to_fixed(b * 255)) <<  8
+                   | cast<U32>(to_fixed(a * 255)) <<  0);
+#else
     store(dst + 4*i, cast<U32>(to_fixed(r * 255)) <<  0
                    | cast<U32>(to_fixed(g * 255)) <<  8
                    | cast<U32>(to_fixed(b * 255)) << 16
                    | cast<U32>(to_fixed(a * 255)) << 24);
+#endif
 }
 
 FINAL_STAGE(store_101010x_XR, NoCtx) {
@@ -1377,16 +1493,31 @@
     uint16_t* rgb = (uint16_t*)ptr;          // for this cast to uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x3_t v = {{
+#if defined(SKCMS_BIG_ENDIAN)
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(r))),
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(g))),
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(b))),
+#else
         (uint16x4_t)U16_from_F(r),
         (uint16x4_t)U16_from_F(g),
         (uint16x4_t)U16_from_F(b),
+#endif
     }};
     vst3_u16(rgb, v);
 #else
+#if defined(SKCMS_BIG_ENDIAN)
+    U32 R = to_fixed(r * 65535),
+        G = to_fixed(g * 65535),
+      B = to_fixed(b * 65535);
+    store_3(rgb+0, cast<U16>((R & 0x00ff) << 8 | (R & 0xff00) >> 8) );
+    store_3(rgb+1, cast<U16>((G & 0x00ff) << 8 | (G & 0xff00) >> 8) );
+    store_3(rgb+2, cast<U16>((B & 0x00ff) << 8 | (B & 0xff00) >> 8) );
+#else
     store_3(rgb+0, U16_from_F(r));
     store_3(rgb+1, U16_from_F(g));
     store_3(rgb+2, U16_from_F(b));
 #endif
+#endif
 
 }
 
@@ -1396,19 +1527,34 @@
     uint16_t* rgba = (uint16_t*)ptr;        // for this cast to uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x4_t v = {{
+#if defined(SKCMS_BIG_ENDIAN)
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(r))),
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(g))),
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(b))),
+        (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(a))),
+#else
         (uint16x4_t)U16_from_F(r),
         (uint16x4_t)U16_from_F(g),
         (uint16x4_t)U16_from_F(b),
         (uint16x4_t)U16_from_F(a),
+#endif
     }};
     vst4_u16(rgba, v);
 #else
+#if defined(SKCMS_BIG_ENDIAN)
+    U64 px = cast<U64>(to_fixed(r * 65535)) << 48
+           | cast<U64>(to_fixed(g * 65535)) << 32
+           | cast<U64>(to_fixed(b * 65535)) << 16
+           | cast<U64>(to_fixed(a * 65535)) <<  0;
+    store(rgba, swap_endian_16x4(px));
+#else
     U64 px = cast<U64>(to_fixed(r * 65535)) <<  0
            | cast<U64>(to_fixed(g * 65535)) << 16
            | cast<U64>(to_fixed(b * 65535)) << 32
            | cast<U64>(to_fixed(a * 65535)) << 48;
     store(rgba, px);
 #endif
+#endif
 }
 
 FINAL_STAGE(store_161616BE, NoCtx) {
@@ -1417,12 +1563,23 @@
     uint16_t* rgb = (uint16_t*)ptr;          // for this cast to uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x3_t v = {{
+#if defined(SKCMS_BIG_ENDIAN)
+        (uint16x4_t)U16_from_F(r),
+        (uint16x4_t)U16_from_F(g),
+        (uint16x4_t)U16_from_F(b),
+#else
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(r))),
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(g))),
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(b))),
+#endif
     }};
     vst3_u16(rgb, v);
 #else
+#if defined(SKCMS_BIG_ENDIAN)
+    store_3(rgb+0, U16_from_F(r));
+    store_3(rgb+1, U16_from_F(g));
+    store_3(rgb+2, U16_from_F(b));
+#else
     U32 R = to_fixed(r * 65535),
         G = to_fixed(g * 65535),
         B = to_fixed(b * 65535);
@@ -1430,6 +1587,7 @@
     store_3(rgb+1, cast<U16>((G & 0x00ff) << 8 | (G & 0xff00) >> 8) );
     store_3(rgb+2, cast<U16>((B & 0x00ff) << 8 | (B & 0xff00) >> 8) );
 #endif
+#endif
 
 }
 
@@ -1439,19 +1597,34 @@
     uint16_t* rgba = (uint16_t*)ptr;        // for this cast to uint16_t* to be safe.
 #if defined(USING_NEON)
     uint16x4x4_t v = {{
+#if defined(SKCMS_BIG_ENDIAN)
+        (uint16x4_t)U16_from_F(r),
+        (uint16x4_t)U16_from_F(g),
+        (uint16x4_t)U16_from_F(b),
+        (uint16x4_t)U16_from_F(a),
+#else
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(r))),
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(g))),
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(b))),
         (uint16x4_t)swap_endian_16(cast<U16>(U16_from_F(a))),
+#endif
     }};
     vst4_u16(rgba, v);
 #else
+#if defined(SKCMS_BIG_ENDIAN)
+    U64 px = cast<U64>(to_fixed(r * 65535)) << 48
+           | cast<U64>(to_fixed(g * 65535)) << 32
+           | cast<U64>(to_fixed(b * 65535)) << 16
+           | cast<U64>(to_fixed(a * 65535)) <<  0;
+    store(rgba, px);
+#else
     U64 px = cast<U64>(to_fixed(r * 65535)) <<  0
            | cast<U64>(to_fixed(g * 65535)) << 16
            | cast<U64>(to_fixed(b * 65535)) << 32
            | cast<U64>(to_fixed(a * 65535)) << 48;
     store(rgba, swap_endian_16x4(px));
 #endif
+#endif
 }
 
 FINAL_STAGE(store_hhh, NoCtx) {
@@ -1494,11 +1667,18 @@
     }};
     vst4_u16(rgba, v);
 #else
+#if defined(SKCMS_BIG_ENDIAN)
+    store(rgba, cast<U64>(R) << 48
+              | cast<U64>(G) << 32
+              | cast<U64>(B) << 16
+              | cast<U64>(A) <<  0);
+#else
     store(rgba, cast<U64>(R) <<  0
               | cast<U64>(G) << 16
               | cast<U64>(B) << 32
               | cast<U64>(A) << 48);
 #endif
+#endif
 }
 
 FINAL_STAGE(store_fff, NoCtx) {
