diff options
-rw-r--r-- | third_party/skcms/skcms.h | 8 | ||||
-rw-r--r-- | third_party/skcms/src/Transform.c | 17 | ||||
-rw-r--r-- | third_party/skcms/src/Transform.h | 6 | ||||
-rw-r--r-- | third_party/skcms/src/Transform_inl.h | 41 | ||||
-rwxr-xr-x | third_party/skcms/version.sha1 | 2 |
5 files changed, 73 insertions, 1 deletions
diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h index 97728c4c8f..abc604be56 100644 --- a/third_party/skcms/skcms.h +++ b/third_party/skcms/skcms.h @@ -166,9 +166,17 @@ enum { }; typedef enum skcms_PixelFormat { + skcms_PixelFormat_A_8, + skcms_PixelFormat_A_8_, + skcms_PixelFormat_G_8, + skcms_PixelFormat_G_8_, + skcms_PixelFormat_RGB_565, skcms_PixelFormat_BGR_565, + skcms_PixelFormat_ABGR_4444, + skcms_PixelFormat_ARGB_4444, + skcms_PixelFormat_RGB_888, skcms_PixelFormat_BGR_888, skcms_PixelFormat_RGBA_8888, diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c index f07c5e7ba4..ebfd0cef5b 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -354,6 +354,9 @@ static OpAndArg select_curve_op(const skcms_Curve* curve, int channel) { static size_t bytes_per_pixel(skcms_PixelFormat fmt) { switch (fmt >> 1) { // ignore rgb/bgr + case skcms_PixelFormat_A_8 >> 1: return 1; + case skcms_PixelFormat_G_8 >> 1: return 1; + case skcms_PixelFormat_ABGR_4444 >> 1: return 2; case skcms_PixelFormat_RGB_565 >> 1: return 2; case skcms_PixelFormat_RGB_888 >> 1: return 3; case skcms_PixelFormat_RGBA_8888 >> 1: return 4; @@ -430,6 +433,9 @@ bool skcms_Transform(const void* src, switch (srcFmt >> 1) { default: return false; + case skcms_PixelFormat_A_8 >> 1: *ops++ = Op_load_a8; break; + case skcms_PixelFormat_G_8 >> 1: *ops++ = Op_load_g8; break; + case skcms_PixelFormat_ABGR_4444 >> 1: *ops++ = Op_load_4444; break; case skcms_PixelFormat_RGB_565 >> 1: *ops++ = Op_load_565; break; case skcms_PixelFormat_RGB_888 >> 1: *ops++ = Op_load_888; break; case skcms_PixelFormat_RGBA_8888 >> 1: *ops++ = Op_load_8888; break; @@ -444,6 +450,14 @@ bool skcms_Transform(const void* src, if (srcFmt & 1) { *ops++ = Op_swap_rb; } + skcms_ICCProfile gray_dst_profile; + if ((dstFmt >> 1) == (skcms_PixelFormat_G_8 >> 1)) { + // When transforming to gray, stop at XYZ (by setting toXYZ to identity), then transform + // luminance (Y) by the destination transfer function. + gray_dst_profile = *dstProfile; + skcms_SetXYZD50(&gray_dst_profile, &skcms_XYZD50_profile()->toXYZD50); + dstProfile = &gray_dst_profile; + } if (srcProfile->data_color_space == skcms_Signature_CMYK) { // Photoshop creates CMYK images as inverse CMYK. @@ -585,6 +599,9 @@ bool skcms_Transform(const void* src, } switch (dstFmt >> 1) { default: return false; + case skcms_PixelFormat_A_8 >> 1: *ops++ = Op_store_a8; break; + case skcms_PixelFormat_G_8 >> 1: *ops++ = Op_store_g8; break; + case skcms_PixelFormat_ABGR_4444 >> 1: *ops++ = Op_store_4444; break; case skcms_PixelFormat_RGB_565 >> 1: *ops++ = Op_store_565; break; case skcms_PixelFormat_RGB_888 >> 1: *ops++ = Op_store_888; break; case skcms_PixelFormat_RGBA_8888 >> 1: *ops++ = Op_store_8888; break; diff --git a/third_party/skcms/src/Transform.h b/third_party/skcms/src/Transform.h index 1c4c15b4e3..6eda8992ba 100644 --- a/third_party/skcms/src/Transform.h +++ b/third_party/skcms/src/Transform.h @@ -11,6 +11,9 @@ #define FOREACH_Op(M) \ M(noop) \ + M(load_a8) \ + M(load_g8) \ + M(load_4444) \ M(load_565) \ M(load_888) \ M(load_8888) \ @@ -46,6 +49,9 @@ M(clut_3D_16) \ M(clut_4D_8) \ M(clut_4D_16) \ + M(store_a8) \ + M(store_g8) \ + M(store_4444) \ M(store_565) \ M(store_888) \ M(store_8888) \ diff --git a/third_party/skcms/src/Transform_inl.h b/third_party/skcms/src/Transform_inl.h index 224412bfa4..fd3100aa60 100644 --- a/third_party/skcms/src/Transform_inl.h +++ b/third_party/skcms/src/Transform_inl.h @@ -576,6 +576,28 @@ static void NS(exec_ops)(const Op* ops, const void** args, switch (profile_next_op(*ops++)) { case Op_noop: break; + case Op_load_a8:{ + U8 alpha; + small_memcpy(&alpha, src + i, N); + a = F_from_U8(alpha); + } break; + + case Op_load_g8:{ + U8 gray; + small_memcpy(&gray, src + i, N); + r = g = b = F_from_U8(gray); + } break; + + case Op_load_4444:{ + U16 abgr; + small_memcpy(&abgr, src + 2*i, 2*N); + + r = CAST(F, (abgr >> 12) & 0xf) * (1/15.0f); + g = CAST(F, (abgr >> 8) & 0xf) * (1/15.0f); + b = CAST(F, (abgr >> 4) & 0xf) * (1/15.0f); + a = CAST(F, (abgr >> 0) & 0xf) * (1/15.0f); + } break; + case Op_load_565:{ U16 rgb; small_memcpy(&rgb, src + 2*i, 2*N); @@ -879,6 +901,25 @@ static void NS(exec_ops)(const Op* ops, const void** args, // Notice, from here on down the store_ ops all return, ending the loop. + case Op_store_a8: { + U8 alpha = CAST(U8, to_fixed(a * 255)); + small_memcpy(dst + i, &alpha, N); + } return; + + case Op_store_g8: { + // g should be holding luminance (Y) (r,g,b ~~~> X,Y,Z) + U8 gray = CAST(U8, to_fixed(g * 255)); + small_memcpy(dst + i, &gray, N); + } return; + + case Op_store_4444: { + U16 abgr = CAST(U16, to_fixed(r * 15) << 12) + | CAST(U16, to_fixed(g * 15) << 8) + | CAST(U16, to_fixed(b * 15) << 4) + | CAST(U16, to_fixed(a * 15) << 0); + small_memcpy(dst + 2*i, &abgr, 2*N); + } return; + case Op_store_565: { U16 rgb = CAST(U16, to_fixed(r * 31) << 0 ) | CAST(U16, to_fixed(g * 63) << 5 ) diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1 index 52ffc8c575..d11bdb2f1a 100755 --- a/third_party/skcms/version.sha1 +++ b/third_party/skcms/version.sha1 @@ -1 +1 @@ -78ef7c5c81fb084fa67c7994501c3edd86aef909
\ No newline at end of file +97bcdb1d73a1f9314a29303a7e16a71cb6856f76
\ No newline at end of file |