From 916ea9405278b2fb979da184c9ea65f8a96548f7 Mon Sep 17 00:00:00 2001 From: Arjen Nienhuis Date: Sun, 7 Aug 2016 15:34:45 +0200 Subject: [PATCH] Add packing from RGBA to BGRa --- Tests/test_mode_bgra.py | 23 +++++++++++++++++++++++ libImaging/Pack.c | 20 ++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Tests/test_mode_bgra.py diff --git a/Tests/test_mode_bgra.py b/Tests/test_mode_bgra.py new file mode 100644 index 000000000..331be4d93 --- /dev/null +++ b/Tests/test_mode_bgra.py @@ -0,0 +1,23 @@ +from helper import unittest, PillowTestCase + +from PIL import Image + + +class TestBGRa(PillowTestCase): + + def test_bgra(self): + RGBA_RED_50 = b'\xff\x00\x00\x80' # 50% red RGBA + BGRa_RED_50 = b'\x00\x00\x80\x80' # 50% red BGRa + RGBa_RED_50 = b'\x80\x00\x00\x80' # 50% red RGBa + + im = Image.frombuffer("RGBA", (1, 1), BGRa_RED_50, "raw", "BGRa", 4, 1) + self.assertEqual(im.tobytes(), RGBA_RED_50) + self.assertEqual(im.tobytes('raw', 'BGRa'), BGRa_RED_50) + + im = Image.frombuffer("RGBa", (1, 1), BGRa_RED_50, "raw", "BGRa", 4, 1) + self.assertEqual(im.tobytes(), RGBa_RED_50) + self.assertEqual(im.tobytes('raw', 'BGRa'), BGRa_RED_50) + + +if __name__ == '__main__': + unittest.main() diff --git a/libImaging/Pack.c b/libImaging/Pack.c index d83cb8284..acbfc8143 100644 --- a/libImaging/Pack.c +++ b/libImaging/Pack.c @@ -72,6 +72,10 @@ #define C64L C64N #endif +/* like (a * b + 127) / 255), but much faster on most platforms */ +#define MULDIV255(a, b, tmp)\ + (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) + static void pack1(UINT8* out, const UINT8* in, int pixels) { @@ -315,6 +319,21 @@ ImagingPackABGR(UINT8* out, const UINT8* in, int pixels) } } +void +ImagingPackBGRa(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* BGRa, reversed bytes with premultiplied alplha */ + for (i = 0; i < pixels; i++) { + int alpha = out[3] = in[A]; + int tmp; + out[0] = MULDIV255(in[B], alpha, tmp); + out[1] = MULDIV255(in[G], alpha, tmp); + out[2] = MULDIV255(in[R], alpha, tmp); + out += 4; in += 4; + } +} + static void packRGBL(UINT8* out, const UINT8* in, int pixels) { @@ -525,6 +544,7 @@ static struct { {"RGBA", "BGR", 24, ImagingPackBGR}, {"RGBA", "BGRA", 32, ImagingPackBGRA}, {"RGBA", "ABGR", 32, ImagingPackABGR}, + {"RGBA", "BGRa", 32, ImagingPackBGRa}, {"RGBA", "R", 8, band0}, {"RGBA", "G", 8, band1}, {"RGBA", "B", 8, band2},