From a1ebae255c30ab0d8a20468db5a6131a9608c2bf Mon Sep 17 00:00:00 2001
From: Eric Soroos <eric-github@soroos.net>
Date: Wed, 9 Aug 2017 13:22:58 +0100
Subject: [PATCH 01/14] basic support for termux (android) support (tested on
 chromeos/x86)

---
 depends/termux.sh | 5 +++++
 setup.py          | 8 ++++++++
 2 files changed, 13 insertions(+)
 create mode 100755 depends/termux.sh

diff --git a/depends/termux.sh b/depends/termux.sh
new file mode 100755
index 000000000..58abccfdd
--- /dev/null
+++ b/depends/termux.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+pkg -y install -y install python python-dev ndk-sysroot clang make \
+    libjpeg-turbo-dev 
+
diff --git a/setup.py b/setup.py
index 1cbfc259a..f378362e6 100755
--- a/setup.py
+++ b/setup.py
@@ -365,6 +365,14 @@ class pil_build_ext(build_ext):
                 # work ;-)
                 self.add_multiarch_paths()
 
+                # termux support for android.
+                # system libraries (zlib) are installed in /system/lib
+                # headers are at $PREFIX/include
+                # user libs are at $PREFIX/lib
+                if os.environ.get('ANDROID_ROOT', None):
+                    _add_directory(library_dirs,
+                                  os.path.join(os.environ['ANDROID_ROOT'],'lib'))
+
         elif sys.platform.startswith("gnu"):
             self.add_multiarch_paths()
 

From 300dfcf4a4426e3b8beb26c26ff60e7df18e63a1 Mon Sep 17 00:00:00 2001
From: wiredfool <eric-github@soroos.net>
Date: Wed, 16 Aug 2017 11:46:27 -0700
Subject: [PATCH 02/14] Test/fix for issue #2044

---
 PIL/Image.py        |  2 +-
 Tests/test_numpy.py | 16 ++++++++++++----
 libImaging/Unpack.c | 14 ++++++++++++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/PIL/Image.py b/PIL/Image.py
index fd96a797f..e6ae18517 100644
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -2423,7 +2423,7 @@ def fromqpixmap(im):
 _fromarray_typemap = {
     # (shape, typestr) => mode, rawmode
     # first two members of shape are set to one
-    # ((1, 1), "|b1"): ("1", "1"), # broken
+    ((1, 1), "|b1"): ("1", "1;8"), 
     ((1, 1), "|u1"): ("L", "L"),
     ((1, 1), "|i1"): ("I", "I;8"),
     ((1, 1), "<u2"): ("I", "I;16"),
diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py
index 74825cd41..792ab603e 100644
--- a/Tests/test_numpy.py
+++ b/Tests/test_numpy.py
@@ -39,7 +39,7 @@ class TestNumpy(PillowTestCase):
         def to_image(dtype, bands=1, boolean=0):
             if bands == 1:
                 if boolean:
-                    data = [0, 1] * 50
+                    data = [0, 255] * 50
                 else:
                     data = list(range(100))
                 a = numpy.array(data, dtype=dtype)
@@ -58,9 +58,9 @@ class TestNumpy(PillowTestCase):
             return i
 
         # Check supported 1-bit integer formats
-        self.assertRaises(TypeError, lambda: to_image(numpy.bool))
-        self.assertRaises(TypeError, lambda: to_image(numpy.bool8))
-
+        self.assert_image(to_image(numpy.bool, 1, 1), '1', TEST_IMAGE_SIZE)
+        self.assert_image(to_image(numpy.bool8, 1, 1), '1', TEST_IMAGE_SIZE)
+        
         # Check supported 8-bit integer formats
         self.assert_image(to_image(numpy.uint8), "L", TEST_IMAGE_SIZE)
         self.assert_image(to_image(numpy.uint8, 3), "RGB", TEST_IMAGE_SIZE)
@@ -213,5 +213,13 @@ class TestNumpy(PillowTestCase):
         self.assertEqual(im.size, (0, 0))
 
 
+    def test_bool(self):
+        # https://github.com/python-pillow/Pillow/issues/2044
+        a = numpy.zeros((10,2), dtype=numpy.bool)
+        a[0][0] = True 
+
+        im2 = Image.fromarray(a)
+        self.assertEqual(im2.getdata()[0], 255)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/libImaging/Unpack.c b/libImaging/Unpack.c
index dfc8a4d7e..05f98095d 100644
--- a/libImaging/Unpack.c
+++ b/libImaging/Unpack.c
@@ -185,6 +185,19 @@ unpack1IR(UINT8* out, const UINT8* in, int pixels)
     }
 }
 
+static void
+unpack18(UINT8* out, const UINT8* in, int pixels)
+{
+    /* Unpack a '|b1' image, which is a numpy boolean. 
+       1 == true, 0==false, in bytes */
+
+    int i;
+    for (i = 0; i < pixels; i++) {
+        out[i] = in[i] > 0 ? 255 : 0;
+    }
+}
+
+
 
 /* Unpack to "L" image */
 
@@ -1168,6 +1181,7 @@ static struct {
     {"1",       "1;I",          1,      unpack1I},
     {"1",       "1;R",          1,      unpack1R},
     {"1",       "1;IR",         1,      unpack1IR},
+    {"1",       "1;8",          1,      unpack18},
 
     /* greyscale */
     {"L",       "L;2",          2,      unpackL2},

From 010e6a46e934c948df9f7cd973d98fcedbe994d5 Mon Sep 17 00:00:00 2001
From: wiredfool <eric-github@soroos.net>
Date: Wed, 16 Aug 2017 20:21:58 +0100
Subject: [PATCH 03/14] Typo fix

---
 depends/termux.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/depends/termux.sh b/depends/termux.sh
index 58abccfdd..f117790c5 100755
--- a/depends/termux.sh
+++ b/depends/termux.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 
-pkg -y install -y install python python-dev ndk-sysroot clang make \
+pkg -y install python python-dev ndk-sysroot clang make \
     libjpeg-turbo-dev 
 

From 8e8643d1ac0a1e6de256434c3da0e528d5fc209f Mon Sep 17 00:00:00 2001
From: wiredfool <eric-github@soroos.net>
Date: Thu, 17 Aug 2017 12:55:29 +0100
Subject: [PATCH 04/14] Update CHANGES.rst [ci skip]

---
 CHANGES.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/CHANGES.rst b/CHANGES.rst
index b72e5a307..8dedfe866 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,6 +4,12 @@ Changelog (Pillow)
 4.3.0 (unreleased)
 ------------------
 
+- Basic support for Termux (android) in setup.py #2684
+  [wiredfool]
+
+- Bug: Fix Image.fromarray for numpy.bool type. #2683
+  [wiredfool]
+
 - CI: Add Fedora 24 and 26 to Docker tests
   [wiredfool]
 
@@ -31,6 +37,9 @@ Changelog (Pillow)
 - Remove unused im.copy2 and core.copy methods #2657
   [homm]
 
+- Fast Image.merge() #2677
+  [homm]
+  
 - Fast Image.split() #2676
   [homm]
 

From f012fa15dd300ff1dd8df50734693dd27daa7ff1 Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Wed, 23 Aug 2017 01:32:10 +0300
Subject: [PATCH 05/14] First part of unpack tests

---
 Tests/test_lib_pack.py | 196 +++++++++++++++++++++++++++--------------
 1 file changed, 129 insertions(+), 67 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index 83872c5d1..9c7f348ee 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -71,73 +71,6 @@ class TestLibPack(PillowTestCase):
 
             return im.getpixel((0, 0))
 
-        def unpack_1(mode, rawmode, value):
-            assert mode == "1"
-            im = None
-
-            if py3:
-                im = Image.frombytes(
-                    mode, (8, 1), bytes([value]), "raw", rawmode, 0, 1)
-            else:
-                im = Image.frombytes(
-                    mode, (8, 1), chr(value), "raw", rawmode, 0, 1)
-
-            return tuple(im.getdata())
-
-        X = 255
-
-        self.assertEqual(unpack_1("1", "1", 1), (0, 0, 0, 0, 0, 0, 0, X))
-        self.assertEqual(unpack_1("1", "1;I", 1), (X, X, X, X, X, X, X, 0))
-        self.assertEqual(unpack_1("1", "1;R", 1), (X, 0, 0, 0, 0, 0, 0, 0))
-        self.assertEqual(unpack_1("1", "1;IR", 1), (0, X, X, X, X, X, X, X))
-
-        self.assertEqual(unpack_1("1", "1", 170), (X, 0, X, 0, X, 0, X, 0))
-        self.assertEqual(unpack_1("1", "1;I", 170), (0, X, 0, X, 0, X, 0, X))
-        self.assertEqual(unpack_1("1", "1;R", 170), (0, X, 0, X, 0, X, 0, X))
-        self.assertEqual(unpack_1("1", "1;IR", 170), (X, 0, X, 0, X, 0, X, 0))
-
-        self.assertEqual(unpack("L", "L;2", 1), 0)
-        self.assertEqual(unpack("L", "L;4", 1), 0)
-        self.assertEqual(unpack("L", "L", 1), 1)
-        self.assertEqual(unpack("L", "L;I", 1), 254)
-        self.assertEqual(unpack("L", "L;R", 1), 128)
-        self.assertEqual(unpack("L", "L;16", 2), 2)  # little endian
-        self.assertEqual(unpack("L", "L;16B", 2), 1)  # big endian
-
-        self.assertEqual(unpack("LA", "LA", 2), (1, 2))
-        self.assertEqual(unpack("LA", "LA;L", 2), (1, 2))
-
-        self.assertEqual(unpack("RGB", "RGB", 3), (1, 2, 3))
-        self.assertEqual(unpack("RGB", "RGB;L", 3), (1, 2, 3))
-        self.assertEqual(unpack("RGB", "RGB;R", 3), (128, 64, 192))
-        self.assertEqual(unpack("RGB", "RGB;16B", 6), (1, 3, 5))  # ?
-        self.assertEqual(unpack("RGB", "BGR", 3), (3, 2, 1))
-        self.assertEqual(unpack("RGB", "RGB;15", 2), (8, 131, 0))
-        self.assertEqual(unpack("RGB", "BGR;15", 2), (0, 131, 8))
-        self.assertEqual(unpack("RGB", "RGB;16", 2), (8, 64, 0))
-        self.assertEqual(unpack("RGB", "BGR;16", 2), (0, 64, 8))
-        self.assertEqual(unpack("RGB", "RGB;4B", 2), (17, 0, 34))
-
-        self.assertEqual(unpack("RGB", "RGBX", 4), (1, 2, 3))
-        self.assertEqual(unpack("RGB", "BGRX", 4), (3, 2, 1))
-        self.assertEqual(unpack("RGB", "XRGB", 4), (2, 3, 4))
-        self.assertEqual(unpack("RGB", "XBGR", 4), (4, 3, 2))
-
-        self.assertEqual(unpack("RGBA", "RGBA", 4), (1, 2, 3, 4))
-        self.assertEqual(unpack("RGBA", "RGBa", 4), (63, 127, 191, 4))
-        self.assertEqual(unpack("RGBA", "BGRA", 4), (3, 2, 1, 4))
-        self.assertEqual(unpack("RGBA", "BGRa", 4), (191, 127, 63, 4))
-        self.assertEqual(unpack("RGBA", "ARGB", 4), (2, 3, 4, 1))
-        self.assertEqual(unpack("RGBA", "ABGR", 4), (4, 3, 2, 1))
-        self.assertEqual(unpack("RGBA", "RGBA;15", 2), (8, 131, 0, 0))
-        self.assertEqual(unpack("RGBA", "BGRA;15", 2), (0, 131, 8, 0))
-        self.assertEqual(unpack("RGBA", "RGBA;4B", 2), (17, 0, 34, 0))
-
-        self.assertEqual(unpack("RGBa", "RGBa", 4), (1, 2, 3, 4))
-        self.assertEqual(unpack("RGBa", "BGRa", 4), (3, 2, 1, 4))
-        self.assertEqual(unpack("RGBa", "aRGB", 4), (2, 3, 4, 1))
-        self.assertEqual(unpack("RGBa", "aBGR", 4), (4, 3, 2, 1))
-
         self.assertEqual(unpack("RGBX", "RGBX", 4), (1, 2, 3, 4))  # 4->255?
         self.assertEqual(unpack("RGBX", "BGRX", 4), (3, 2, 1, 255))
         self.assertEqual(unpack("RGBX", "XRGB", 4), (2, 3, 4, 255))
@@ -154,5 +87,134 @@ class TestLibPack(PillowTestCase):
         self.assertRaises(ValueError, lambda: unpack("CMYK", "CMYK", 2))
 
 
+class TestLibUnpack(PillowTestCase):
+    def assert_unpack(self, mode, rawmode, data, *pixels):
+        """
+        data - eather raw bytes with data or just number of bytes in rawmode.
+        """
+        if isinstance(data, (int)):
+            data_len = data * len(pixels)
+            data = bytes(bytearray(range(1, data_len + 1)))
+
+        im = Image.frombytes(mode, (len(pixels), 1), data, "raw", rawmode, 0, 1)
+
+        for x, pixel in enumerate(pixels):
+            self.assertEqual(pixel, im.getpixel((x, 0)))
+
+    def test_1(self):
+        X = 255
+
+        self.assert_unpack("1", "1", b'\x01', 0, 0, 0, 0, 0, 0, 0, X)
+        self.assert_unpack("1", "1;I", b'\x01', X, X, X, X, X, X, X, 0)
+        self.assert_unpack("1", "1;R", b'\x01', X, 0, 0, 0, 0, 0, 0, 0)
+        self.assert_unpack("1", "1;IR", b'\x01', 0, X, X, X, X, X, X, X)
+
+        self.assert_unpack("1", "1", b'\xaa', X, 0, X, 0, X, 0, X, 0)
+        self.assert_unpack("1", "1;I", b'\xaa', 0, X, 0, X, 0, X, 0, X)
+        self.assert_unpack("1", "1;R", b'\xaa', 0, X, 0, X, 0, X, 0, X)
+        self.assert_unpack("1", "1;IR", b'\xaa', X, 0, X, 0, X, 0, X, 0)
+
+        self.assert_unpack("1", "1;8", b'\x00\x01\x02\xff', 0, X, X, X)
+
+    def test_L(self):
+        self.assert_unpack("L", "L;2", b'\xe4', 255, 170, 85, 0)
+        self.assert_unpack("L", "L;2I", b'\xe4', 0, 85, 170, 255)
+        self.assert_unpack("L", "L;2R", b'\xe4', 0, 170, 85, 255)
+        self.assert_unpack("L", "L;2IR", b'\xe4', 255, 85, 170, 0)
+
+        self.assert_unpack("L", "L;4", b'\x02\xef', 0, 34, 238, 255)
+        self.assert_unpack("L", "L;4I", b'\x02\xef', 255, 221, 17, 0)
+        self.assert_unpack("L", "L;4R", b'\x02\xef', 68, 0, 255, 119)
+        self.assert_unpack("L", "L;4IR", b'\x02\xef', 187, 255, 0, 136)
+
+        self.assert_unpack("L", "L", 1, 1, 2, 3, 4)
+        self.assert_unpack("L", "L;I", 1, 254, 253, 252, 251)
+        self.assert_unpack("L", "L;R", 1, 128, 64, 192, 32)
+        self.assert_unpack("L", "L;16", 2, 2, 4, 6, 8)
+        self.assert_unpack("L", "L;16B", 2, 1, 3, 5, 7)
+
+    def test_LA(self):
+        self.assert_unpack("LA", "LA", 2, (1, 2), (3, 4), (5, 6))
+        self.assert_unpack("LA", "LA;L", 2, (1, 4), (2, 5), (3, 6))
+
+    def test_P(self):
+        self.assert_unpack("P", "P;1", b'\xe4', 1, 1, 1, 0, 0, 1, 0, 0)
+        self.assert_unpack("P", "P;2", b'\xe4', 3, 2, 1, 0)
+        # self.assert_unpack("P", "P;2L", b'\xe4', 1, 1, 1, 0)  # erroneous?
+        self.assert_unpack("P", "P;4", b'\x02\xef', 0, 2, 14, 15)
+        # self.assert_unpack("P", "P;4L", b'\x02\xef', 2, 10, 10, 0)  # erroneous?
+        self.assert_unpack("P", "P", 1, 1, 2, 3, 4)
+        self.assert_unpack("P", "P;R", 1, 128, 64, 192, 32)
+
+    def test_PA(self):
+        self.assert_unpack("PA", "PA", 2, (1, 2), (3, 4), (5, 6))
+        self.assert_unpack("PA", "PA;L", 2, (1, 4), (2, 5), (3, 6))
+
+    def test_RGB(self):
+        self.assert_unpack("RGB", "RGB", 3, (1,2,3), (4,5,6), (7,8,9))
+        self.assert_unpack("RGB", "RGB;L", 3, (1,4,7), (2,5,8), (3,6,9))
+        self.assert_unpack("RGB", "RGB;R", 3, (128,64,192), (32,160,96))
+        self.assert_unpack("RGB", "RGB;16B", 6, (1,3,5), (7,9,11))
+        self.assert_unpack("RGB", "BGR", 3, (3,2,1), (6,5,4), (9,8,7))
+        self.assert_unpack("RGB", "RGB;15", 2, (8,131,0), (24,0,8))
+        self.assert_unpack("RGB", "BGR;15", 2, (0,131,8), (8,0,24))
+        self.assert_unpack("RGB", "RGB;16", 2, (8,64,0), (24,129,0))
+        self.assert_unpack("RGB", "BGR;16", 2, (0,64,8), (0,129,24))
+        self.assert_unpack("RGB", "RGB;4B", 2, (17,0,34), (51,0,68))
+        self.assert_unpack("RGB", "RGBX", 4, (1,2,3), (5,6,7), (9,10,11))
+        self.assert_unpack("RGB", "RGBX;L", 4, (1,4,7), (2,5,8), (3,6,9))
+        self.assert_unpack("RGB", "BGRX", 4, (3,2,1), (7,6,5), (11,10,9))
+        self.assert_unpack("RGB", "XRGB", 4, (2,3,4), (6,7,8), (10,11,12))
+        self.assert_unpack("RGB", "XBGR", 4, (4,3,2), (8,7,6), (12,11,10))
+        self.assert_unpack("RGB", "YCC;P",
+            b'D]\x9c\x82\x1a\x91\xfaOC\xe7J\x12',  # random data
+            (127,102,0), (192,227,0), (213,255,170), (98,255,133))
+        self.assert_unpack("RGB", "R", 1, (1,0,0), (2,0,0), (3,0,0))
+        self.assert_unpack("RGB", "G", 1, (0,1,0), (0,2,0), (0,3,0))
+        self.assert_unpack("RGB", "B", 1, (0,0,1), (0,0,2), (0,0,3))
+
+    def test_RGBA(self):
+        self.assert_unpack("RGBA", "LA", 2, (1,1,1,2), (3,3,3,4), (5,5,5,6))
+        self.assert_unpack("RGBA", "LA;16B", 4,
+            (1,1,1,3), (5,5,5,7), (9,9,9,11))
+        self.assert_unpack("RGBA", "RGBA", 4,
+            (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_unpack("RGBA", "RGBa", 4,
+            (63,127,191,4), (159,191,223,8), (191,212,233,12))
+        self.assert_unpack("RGBA", "BGRa", 4,
+            (191,127,63,4), (223,191,159,8), (233,212,191,12))
+        self.assert_unpack("RGBA", "RGBA;I", 4,
+            (254,253,252,4), (250,249,248,8), (246,245,244,12))
+        self.assert_unpack("RGBA", "RGBA;L", 4,
+            (1,4,7,10), (2,5,8,11), (3,6,9,12))
+        self.assert_unpack("RGBA", "RGBA;15", 2, (8,131,0,0), (24,0,8,0))
+        self.assert_unpack("RGBA", "BGRA;15", 2, (0,131,8,0), (8,0,24,0))
+        self.assert_unpack("RGBA", "RGBA;4B", 2, (17,0,34,0), (51,0,68,0))
+        self.assert_unpack("RGBA", "RGBA;16B", 8, (1,3,5,7), (9,11,13,15))
+        self.assert_unpack("RGBA", "BGRA", 4,
+            (3,2,1,4), (7,6,5,8), (11,10,9,12))
+        self.assert_unpack("RGBA", "ARGB", 4,
+            (2,3,4,1), (6,7,8,5), (10,11,12,9))
+        self.assert_unpack("RGBA", "ABGR", 4,
+            (4,3,2,1), (8,7,6,5), (12,11,10,9))
+        self.assert_unpack("RGBA", "YCCA;P",
+            b']bE\x04\xdd\xbej\xed57T\xce\xac\xce:\x11',  # random data
+            (0,161,0,4), (255,255,255,237), (27,158,0,206), (0,118,0,17))
+        self.assert_unpack("RGBA", "R", 1, (1,0,0,0), (2,0,0,0), (3,0,0,0))
+        self.assert_unpack("RGBA", "G", 1, (0,1,0,0), (0,2,0,0), (0,3,0,0))
+        self.assert_unpack("RGBA", "B", 1, (0,0,1,0), (0,0,2,0), (0,0,3,0))
+        self.assert_unpack("RGBA", "A", 1, (0,0,0,1), (0,0,0,2), (0,0,0,3))
+
+    def test_RGBa(self):
+        self.assert_unpack("RGBa", "RGBa", 4,
+            (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_unpack("RGBa", "BGRa", 4,
+            (3,2,1,4), (7,6,5,8), (11,10,9,12))
+        self.assert_unpack("RGBa", "aRGB", 4,
+            (2,3,4,1), (6,7,8,5), (10,11,12,9))
+        self.assert_unpack("RGBa", "aBGR", 4,
+            (4,3,2,1), (8,7,6,5), (12,11,10,9))
+
+
 if __name__ == '__main__':
     unittest.main()

From 5c2199c97b3280c29f335e22921a9f8435e8fd0e Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Wed, 23 Aug 2017 01:55:55 +0300
Subject: [PATCH 06/14] Second part of unpack tests

---
 Tests/test_lib_pack.py | 78 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 64 insertions(+), 14 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index 9c7f348ee..5a02511da 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -3,6 +3,9 @@ from helper import unittest, PillowTestCase, py3
 from PIL import Image
 
 
+X = 255
+
+
 class TestLibPack(PillowTestCase):
 
     def pack(self):
@@ -58,7 +61,6 @@ class TestLibPack(PillowTestCase):
         self.assertEqual(pack("YCbCr", "YCbCr"), [1, 2, 3])
 
     def test_unpack(self):
-
         def unpack(mode, rawmode, bytes_):
             im = None
 
@@ -71,17 +73,6 @@ class TestLibPack(PillowTestCase):
 
             return im.getpixel((0, 0))
 
-        self.assertEqual(unpack("RGBX", "RGBX", 4), (1, 2, 3, 4))  # 4->255?
-        self.assertEqual(unpack("RGBX", "BGRX", 4), (3, 2, 1, 255))
-        self.assertEqual(unpack("RGBX", "XRGB", 4), (2, 3, 4, 255))
-        self.assertEqual(unpack("RGBX", "XBGR", 4), (4, 3, 2, 255))
-        self.assertEqual(unpack("RGBX", "RGB;15", 2), (8, 131, 0, 255))
-        self.assertEqual(unpack("RGBX", "BGR;15", 2), (0, 131, 8, 255))
-        self.assertEqual(unpack("RGBX", "RGB;4B", 2), (17, 0, 34, 255))
-
-        self.assertEqual(unpack("CMYK", "CMYK", 4), (1, 2, 3, 4))
-        self.assertEqual(unpack("CMYK", "CMYK;I", 4), (254, 253, 252, 251))
-
         self.assertRaises(ValueError, lambda: unpack("L", "L", 0))
         self.assertRaises(ValueError, lambda: unpack("RGB", "RGB", 2))
         self.assertRaises(ValueError, lambda: unpack("CMYK", "CMYK", 2))
@@ -102,8 +93,6 @@ class TestLibUnpack(PillowTestCase):
             self.assertEqual(pixel, im.getpixel((x, 0)))
 
     def test_1(self):
-        X = 255
-
         self.assert_unpack("1", "1", b'\x01', 0, 0, 0, 0, 0, 0, 0, X)
         self.assert_unpack("1", "1;I", b'\x01', X, X, X, X, X, X, X, 0)
         self.assert_unpack("1", "1;R", b'\x01', X, 0, 0, 0, 0, 0, 0, 0)
@@ -215,6 +204,67 @@ class TestLibUnpack(PillowTestCase):
         self.assert_unpack("RGBa", "aBGR", 4,
             (4,3,2,1), (8,7,6,5), (12,11,10,9))
 
+    def test_RGBX(self):
+        self.assert_unpack("RGBX", "RGB", 3, (1,2,3,X), (4,5,6,X), (7,8,9,X))
+        self.assert_unpack("RGBX", "RGB;L", 3, (1,4,7,X), (2,5,8,X), (3,6,9,X))
+        self.assert_unpack("RGBX", "RGB;16B", 6, (1,3,5,X), (7,9,11,X))
+        self.assert_unpack("RGBX", "BGR", 3, (3,2,1,X), (6,5,4,X), (9,8,7,X))
+        self.assert_unpack("RGBX", "RGB;15", 2, (8,131,0,X), (24,0,8,X))
+        self.assert_unpack("RGBX", "BGR;15", 2, (0,131,8,X), (8,0,24,X))
+        self.assert_unpack("RGBX", "RGB;4B", 2, (17,0,34,X), (51,0,68,X))
+        self.assert_unpack("RGBX", "RGBX", 4,
+            (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_unpack("RGBX", "RGBX;L", 4,
+            (1,4,7,10), (2,5,8,11), (3,6,9,12))
+        self.assert_unpack("RGBX", "BGRX", 4, (3,2,1,X), (7,6,5,X), (11,10,9,X))
+        self.assert_unpack("RGBX", "XRGB", 4, (2,3,4,X), (6,7,8,X), (10,11,12,X))
+        self.assert_unpack("RGBX", "XBGR", 4, (4,3,2,X), (8,7,6,X), (12,11,10,X))
+        self.assert_unpack("RGBX", "YCC;P",
+            b'D]\x9c\x82\x1a\x91\xfaOC\xe7J\x12',  # random data
+            (127,102,0,X), (192,227,0,X), (213,255,170,X), (98,255,133,X))
+        self.assert_unpack("RGBX", "R", 1, (1,0,0,0), (2,0,0,0), (3,0,0,0))
+        self.assert_unpack("RGBX", "G", 1, (0,1,0,0), (0,2,0,0), (0,3,0,0))
+        self.assert_unpack("RGBX", "B", 1, (0,0,1,0), (0,0,2,0), (0,0,3,0))
+        self.assert_unpack("RGBX", "X", 1, (0,0,0,1), (0,0,0,2), (0,0,0,3))
+
+    def test_CMYK(self):
+        self.assert_unpack("CMYK", "CMYK", 4, (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_unpack("CMYK", "CMYK;I", 4,
+            (254,253,252,251), (250,249,248,247), (246,245,244,243))
+        self.assert_unpack("CMYK", "CMYK;L", 4,
+            (1,4,7,10), (2,5,8,11), (3,6,9,12))
+        self.assert_unpack("CMYK", "C", 1, (1,0,0,0), (2,0,0,0), (3,0,0,0))
+        self.assert_unpack("CMYK", "M", 1, (0,1,0,0), (0,2,0,0), (0,3,0,0))
+        self.assert_unpack("CMYK", "Y", 1, (0,0,1,0), (0,0,2,0), (0,0,3,0))
+        self.assert_unpack("CMYK", "K", 1, (0,0,0,1), (0,0,0,2), (0,0,0,3))
+        self.assert_unpack("CMYK", "C;I", 1,
+            (254,0,0,0), (253,0,0,0), (252,0,0,0))
+        self.assert_unpack("CMYK", "M;I", 1,
+            (0,254,0,0), (0,253,0,0), (0,252,0,0))
+        self.assert_unpack("CMYK", "Y;I", 1,
+            (0,0,254,0), (0,0,253,0), (0,0,252,0))
+        self.assert_unpack("CMYK", "K;I", 1,
+            (0,0,0,254), (0,0,0,253), (0,0,0,252))
+
+    def test_YCbCr(self):
+        self.assert_unpack("YCbCr", "YCbCr", 3, (1,2,3), (4,5,6), (7,8,9))
+        self.assert_unpack("YCbCr", "YCbCr;L", 3, (1,4,7), (2,5,8), (3,6,9))
+        self.assert_unpack("YCbCr", "YCbCrX", 4, (1,2,3), (5,6,7), (9,10,11))
+        self.assert_unpack("YCbCr", "YCbCrK", 4, (1,2,3), (5,6,7), (9,10,11))
+
+    def test_LAB(self):
+        self.assert_unpack("LAB", "LAB", 3,
+            (1,130,131), (4,133,134), (7,136,137))
+        self.assert_unpack("LAB", "L", 1, (1,0,0), (2,0,0), (3,0,0))
+        self.assert_unpack("LAB", "A", 1, (0,1,0), (0,2,0), (0,3,0))
+        self.assert_unpack("LAB", "B", 1, (0,0,1), (0,0,2), (0,0,3))
+
+    def test_HSV(self):
+        self.assert_unpack("HSV", "HSV", 3, (1,2,3), (4,5,6), (7,8,9))
+        self.assert_unpack("HSV", "H", 1, (1,0,0), (2,0,0), (3,0,0))
+        self.assert_unpack("HSV", "S", 1, (0,1,0), (0,2,0), (0,3,0))
+        self.assert_unpack("HSV", "V", 1, (0,0,1), (0,0,2), (0,0,3))
+
 
 if __name__ == '__main__':
     unittest.main()

From 29aca0815a0a17f724b88f9b2fefeddff00fab27 Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Wed, 23 Aug 2017 10:27:13 +0300
Subject: [PATCH 07/14] Third part of unpack tests

---
 Tests/test_lib_pack.py | 122 +++++++++++++++++++++++++++++++++++------
 1 file changed, 105 insertions(+), 17 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index 5a02511da..0101d2e18 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -1,3 +1,5 @@
+import sys
+
 from helper import unittest, PillowTestCase, py3
 
 from PIL import Image
@@ -60,23 +62,6 @@ class TestLibPack(PillowTestCase):
         self.assertEqual(pack("CMYK", "CMYK"), [1, 2, 3, 4])
         self.assertEqual(pack("YCbCr", "YCbCr"), [1, 2, 3])
 
-    def test_unpack(self):
-        def unpack(mode, rawmode, bytes_):
-            im = None
-
-            if py3:
-                data = bytes(range(1, bytes_+1))
-            else:
-                data = ''.join(chr(i) for i in range(1, bytes_+1))
-
-            im = Image.frombytes(mode, (1, 1), data, "raw", rawmode, 0, 1)
-
-            return im.getpixel((0, 0))
-
-        self.assertRaises(ValueError, lambda: unpack("L", "L", 0))
-        self.assertRaises(ValueError, lambda: unpack("RGB", "RGB", 2))
-        self.assertRaises(ValueError, lambda: unpack("CMYK", "CMYK", 2))
-
 
 class TestLibUnpack(PillowTestCase):
     def assert_unpack(self, mode, rawmode, data, *pixels):
@@ -265,6 +250,109 @@ class TestLibUnpack(PillowTestCase):
         self.assert_unpack("HSV", "S", 1, (0,1,0), (0,2,0), (0,3,0))
         self.assert_unpack("HSV", "V", 1, (0,0,1), (0,0,2), (0,0,3))
 
+    def test_I(self):
+        self.assert_unpack("I", "I", 4, 0x04030201, 0x08070605)
+        self.assert_unpack("I", "I;8", 1, 0x01, 0x02, 0x03, 0x04)
+        self.assert_unpack("I", "I;8S", b'\x01\x83', 1, -125)
+        self.assert_unpack("I", "I;16", 2, 0x0201, 0x0403)
+        self.assert_unpack("I", "I;16S", b'\x83\x01\x01\x83', 0x0183, -31999)
+        self.assert_unpack("I", "I;16B", 2, 0x0102, 0x0304)
+        self.assert_unpack("I", "I;16BS", b'\x83\x01\x01\x83', -31999, 0x0183)
+        self.assert_unpack("I", "I;32", 4, 0x04030201, 0x08070605)
+        self.assert_unpack("I", "I;32S",
+            b'\x83\x00\x00\x01\x01\x00\x00\x83',
+            0x01000083, -2097151999)
+        self.assert_unpack("I", "I;32B", 4, 0x01020304, 0x05060708)
+        self.assert_unpack("I", "I;32BS",
+            b'\x83\x00\x00\x01\x01\x00\x00\x83',
+            -2097151999, 0x01000083)
+
+        if sys.byteorder == 'little':
+            self.assert_unpack("I", "I;16N", 2, 0x0201, 0x0403)
+            self.assert_unpack("I", "I;16NS", b'\x83\x01\x01\x83', 0x0183, -31999)
+            self.assert_unpack("I", "I;32N", 4, 0x04030201, 0x08070605)
+            self.assert_unpack("I", "I;32NS",
+                b'\x83\x00\x00\x01\x01\x00\x00\x83',
+                0x01000083, -2097151999)
+        else:
+            self.assert_unpack("I", "I;16N", 2, 0x0102, 0x0304)
+            self.assert_unpack("I", "I;16NS", b'\x83\x01\x01\x83', -31999, 0x0183)
+            self.assert_unpack("I", "I;32N", 4, 0x01020304, 0x05060708)
+            self.assert_unpack("I", "I;32NS",
+                b'\x83\x00\x00\x01\x01\x00\x00\x83',
+                -2097151999, 0x01000083)
+
+    def test_F_int(self):
+        self.assert_unpack("F", "F;8", 1, 0x01, 0x02, 0x03, 0x04)
+        self.assert_unpack("F", "F;8S", b'\x01\x83', 1, -125)
+        self.assert_unpack("F", "F;16", 2, 0x0201, 0x0403)
+        self.assert_unpack("F", "F;16S", b'\x83\x01\x01\x83', 0x0183, -31999)
+        self.assert_unpack("F", "F;16B", 2, 0x0102, 0x0304)
+        self.assert_unpack("F", "F;16BS", b'\x83\x01\x01\x83', -31999, 0x0183)
+        self.assert_unpack("F", "F;32", 4, 67305984, 134678016)
+        self.assert_unpack("F", "F;32S",
+            b'\x83\x00\x00\x01\x01\x00\x00\x83',
+            16777348, -2097152000)
+        self.assert_unpack("F", "F;32B", 4, 0x01020304, 0x05060708)
+        self.assert_unpack("F", "F;32BS",
+            b'\x83\x00\x00\x01\x01\x00\x00\x83',
+            -2097152000, 16777348)
+
+        if sys.byteorder == 'little':
+            self.assert_unpack("F", "F;16N", 2, 0x0201, 0x0403)
+            self.assert_unpack("F", "F;16NS", b'\x83\x01\x01\x83', 0x0183, -31999)
+            self.assert_unpack("F", "F;32N", 4, 67305984, 134678016)
+            self.assert_unpack("F", "F;32NS",
+                b'\x83\x00\x00\x01\x01\x00\x00\x83',
+                16777348, -2097152000)
+        else:
+            self.assert_unpack("F", "F;16N", 2, 0x0102, 0x0304)
+            self.assert_unpack("F", "F;16NS", b'\x83\x01\x01\x83', -31999, 0x0183)
+            self.assert_unpack("F", "F;32N", 4, 0x01020304, 0x05060708)
+            self.assert_unpack("F", "F;32NS",
+                b'\x83\x00\x00\x01\x01\x00\x00\x83',
+                -2097152000, 16777348)
+
+    def test_F_float(self):
+        self.assert_unpack("F", "F", 4,
+            1.539989614439558e-36, 4.063216068939723e-34)
+        self.assert_unpack("F", "F;32F", 4,
+            1.539989614439558e-36, 4.063216068939723e-34)
+        self.assert_unpack("F", "F;32BF", 4,
+            2.387939260590663e-38, 6.301941157072183e-36)
+        self.assert_unpack("F", "F;64F",
+            '333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0',  # by struct.pack
+            0.15000000596046448, -1234.5)
+        self.assert_unpack("F", "F;64BF",
+            '?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00',  # by struct.pack
+            0.15000000596046448, -1234.5)
+
+        if sys.byteorder == 'little':
+            self.assert_unpack("F", "F;32NF", 4,
+                1.539989614439558e-36, 4.063216068939723e-34)
+            self.assert_unpack("F", "F;64NF",
+                '333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0',
+                0.15000000596046448, -1234.5)
+        else:
+            self.assert_unpack("F", "F;32NF", 4,
+                2.387939260590663e-38, 6.301941157072183e-36)
+            self.assert_unpack("F", "F;64NF",
+                '?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00',
+                0.15000000596046448, -1234.5)
+
+    def test_I16(self):
+        self.assert_unpack("I;16", "I;16", 2, 0x0201, 0x0403, 0x0605)
+        self.assert_unpack("I;16B", "I;16B", 2, 0x0102, 0x0304, 0x0506)
+        self.assert_unpack("I;16L", "I;16L", 2, 0x0201, 0x0403, 0x0605)
+        self.assert_unpack("I;16", "I;16N", 2, 0x0201, 0x0403, 0x0605)
+        self.assert_unpack("I;16B", "I;16N", 2, 0x0201, 0x0403, 0x0605)
+        self.assert_unpack("I;16L", "I;16N", 2, 0x0201, 0x0403, 0x0605)
+        self.assert_unpack("I;16", "I;12", 2, 0x0010, 0x0203, 0x0040, 0x0506)
+
+    def test_value_error(self):
+        self.assertRaises(ValueError, self.assert_unpack, "L", "L", 0, 0)
+        self.assertRaises(ValueError, self.assert_unpack, "RGB", "RGB", 2, 0)
+        self.assertRaises(ValueError, self.assert_unpack, "CMYK", "CMYK", 2, 0)
 
 if __name__ == '__main__':
     unittest.main()

From d33eab504d4e37c7457d877895a108212b1eb52d Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Wed, 23 Aug 2017 10:52:18 +0300
Subject: [PATCH 08/14] byte strings

---
 Tests/test_lib_pack.py | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index 0101d2e18..4a7e1f844 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -321,23 +321,23 @@ class TestLibUnpack(PillowTestCase):
         self.assert_unpack("F", "F;32BF", 4,
             2.387939260590663e-38, 6.301941157072183e-36)
         self.assert_unpack("F", "F;64F",
-            '333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0',  # by struct.pack
+            b'333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0',  # by struct.pack
             0.15000000596046448, -1234.5)
         self.assert_unpack("F", "F;64BF",
-            '?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00',  # by struct.pack
+            b'?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00',  # by struct.pack
             0.15000000596046448, -1234.5)
 
         if sys.byteorder == 'little':
             self.assert_unpack("F", "F;32NF", 4,
                 1.539989614439558e-36, 4.063216068939723e-34)
             self.assert_unpack("F", "F;64NF",
-                '333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0',
+                b'333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0',
                 0.15000000596046448, -1234.5)
         else:
             self.assert_unpack("F", "F;32NF", 4,
                 2.387939260590663e-38, 6.301941157072183e-36)
             self.assert_unpack("F", "F;64NF",
-                '?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00',
+                b'?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00',
                 0.15000000596046448, -1234.5)
 
     def test_I16(self):
@@ -354,5 +354,6 @@ class TestLibUnpack(PillowTestCase):
         self.assertRaises(ValueError, self.assert_unpack, "RGB", "RGB", 2, 0)
         self.assertRaises(ValueError, self.assert_unpack, "CMYK", "CMYK", 2, 0)
 
+
 if __name__ == '__main__':
     unittest.main()

From a812f6c48035f3d09484bd0dfed1710e3aa8cc22 Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Wed, 23 Aug 2017 23:09:09 +0300
Subject: [PATCH 09/14] fix tests test_I16

---
 Tests/test_lib_pack.py | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index 4a7e1f844..432754088 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -344,10 +344,15 @@ class TestLibUnpack(PillowTestCase):
         self.assert_unpack("I;16", "I;16", 2, 0x0201, 0x0403, 0x0605)
         self.assert_unpack("I;16B", "I;16B", 2, 0x0102, 0x0304, 0x0506)
         self.assert_unpack("I;16L", "I;16L", 2, 0x0201, 0x0403, 0x0605)
-        self.assert_unpack("I;16", "I;16N", 2, 0x0201, 0x0403, 0x0605)
-        self.assert_unpack("I;16B", "I;16N", 2, 0x0201, 0x0403, 0x0605)
-        self.assert_unpack("I;16L", "I;16N", 2, 0x0201, 0x0403, 0x0605)
         self.assert_unpack("I;16", "I;12", 2, 0x0010, 0x0203, 0x0040, 0x0506)
+        if sys.byteorder == 'little':
+            self.assert_unpack("I;16", "I;16N", 2, 0x0201, 0x0403, 0x0605)
+            self.assert_unpack("I;16B", "I;16N", 2, 0x0201, 0x0403, 0x0605)
+            self.assert_unpack("I;16L", "I;16N", 2, 0x0201, 0x0403, 0x0605)
+        else:
+            self.assert_unpack("I;16", "I;16N", 2, 0x0102, 0x0304, 0x0506)
+            self.assert_unpack("I;16B", "I;16N", 2, 0x0102, 0x0304, 0x0506)
+            self.assert_unpack("I;16L", "I;16N", 2, 0x0102, 0x0304, 0x0506)
 
     def test_value_error(self):
         self.assertRaises(ValueError, self.assert_unpack, "L", "L", 0, 0)

From 2439c9b2db63d4497643e031d138aaf80916ab8c Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Wed, 23 Aug 2017 23:09:50 +0300
Subject: [PATCH 10/14] =?UTF-8?q?possible=20fix=20I=E2=86=92I=20and=20L?=
 =?UTF-8?q?=E2=86=92L=20unpacking=20on=20bigendian?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 libImaging/Unpack.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libImaging/Unpack.c b/libImaging/Unpack.c
index 05f98095d..b0fba0a79 100644
--- a/libImaging/Unpack.c
+++ b/libImaging/Unpack.c
@@ -1318,7 +1318,7 @@ static struct {
     {"HSV",  	"V",            8,      band2},
 
     /* integer variations */
-    {"I",       "I",            32,     copy4},
+    {"I",       "I",            32,     unpackI32},
     {"I",       "I;8",          8,      unpackI8},
     {"I",       "I;8S",         8,      unpackI8S},
     {"I",       "I;16",         16,     unpackI16},
@@ -1335,7 +1335,7 @@ static struct {
     {"I",       "I;32NS",       32,     unpackI32NS},
 
     /* floating point variations */
-    {"F",       "F",            32,     copy4},
+    {"F",       "F",            32,     unpackI32},
     {"F",       "F;8",          8,      unpackF8},
     {"F",       "F;8S",         8,      unpackF8S},
     {"F",       "F;16",         16,     unpackF16},

From 8cb9cba1e04c447e6564b9d0da3c36140044cf87 Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Thu, 24 Aug 2017 00:50:17 +0300
Subject: [PATCH 11/14] Packing tests, first part. Fix RGBX packers

---
 Tests/test_lib_pack.py | 132 +++++++++++++++++++++++++++++++----------
 libImaging/Pack.c      |   4 +-
 2 files changed, 104 insertions(+), 32 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index 432754088..d26a18d2e 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -9,10 +9,6 @@ X = 255
 
 
 class TestLibPack(PillowTestCase):
-
-    def pack(self):
-        pass  # not yet
-
     def test_pack(self):
 
         def pack(mode, rawmode, in_data=(1, 2, 3, 4)):
@@ -28,40 +24,116 @@ class TestLibPack(PillowTestCase):
 
         order = 1 if Image._ENDIAN == '<' else -1
 
-        self.assertEqual(pack("1", "1"), [128])
-        self.assertEqual(pack("1", "1;I"), [0])
-        self.assertEqual(pack("1", "1;R"), [1])
-        self.assertEqual(pack("1", "1;IR"), [0])
-
-        self.assertEqual(pack("L", "L"), [1])
 
         self.assertEqual(pack("I", "I"), [1, 0, 0, 0][::order])
 
         self.assertEqual(pack("F", "F"), [0, 0, 128, 63][::order])
 
-        self.assertEqual(pack("LA", "LA"), [1, 2])
-
-        self.assertEqual(pack("RGB", "RGB"), [1, 2, 3])
-        self.assertEqual(pack("RGB", "RGB;L"), [1, 2, 3])
-        self.assertEqual(pack("RGB", "BGR"), [3, 2, 1])
-        self.assertEqual(pack("RGB", "RGBX"), [1, 2, 3, 255])  # 255?
-        self.assertEqual(pack("RGB", "BGRX"), [3, 2, 1, 0])
-        self.assertEqual(pack("RGB", "XRGB"), [0, 1, 2, 3])
-        self.assertEqual(pack("RGB", "XBGR"), [0, 3, 2, 1])
-
-        self.assertEqual(pack("RGBX", "RGBX"), [1, 2, 3, 4])  # 4->255?
-
-        self.assertEqual(pack("RGBA", "RGBA"), [1, 2, 3, 4])
-        self.assertEqual(pack("RGBA", "BGRa"), [0, 0, 0, 4])
-        self.assertEqual(pack("RGBA", "BGRa", in_data=(20, 30, 40, 50)), [8, 6, 4, 50])
-
-        self.assertEqual(pack("RGBa", "RGBa"), [1, 2, 3, 4])
-        self.assertEqual(pack("RGBa", "BGRa"), [3, 2, 1, 4])
-        self.assertEqual(pack("RGBa", "aBGR"), [4, 3, 2, 1])
-
         self.assertEqual(pack("CMYK", "CMYK"), [1, 2, 3, 4])
         self.assertEqual(pack("YCbCr", "YCbCr"), [1, 2, 3])
 
+    def assert_pack(self, mode, rawmode, data, *pixels):
+        """
+        data - eather raw bytes with data or just number of bytes in rawmode.
+        """
+        im = Image.new(mode, (len(pixels), 1))
+        for x, pixel in enumerate(pixels):
+            im.putpixel((x, 0), pixel)
+
+        if isinstance(data, (int)):
+            data_len = data * len(pixels)
+            data = bytes(bytearray(range(1, data_len + 1)))
+
+        self.assertEqual(data, im.tobytes("raw", rawmode))
+
+    def test_1(self):
+        self.assert_pack("1", "1", b'\x01', 0,0,0,0,0,0,0,X)
+        self.assert_pack("1", "1;I", b'\x01', X,X,X,X,X,X,X,0)
+        self.assert_pack("1", "1;R", b'\x01', X,0,0,0,0,0,0,0)
+        self.assert_pack("1", "1;IR", b'\x01', 0,X,X,X,X,X,X,X)
+
+        self.assert_pack("1", "1", b'\xaa', X,0,X,0,X,0,X,0)
+        self.assert_pack("1", "1;I", b'\xaa', 0,X,0,X,0,X,0,X)
+        self.assert_pack("1", "1;R", b'\xaa', 0,X,0,X,0,X,0,X)
+        self.assert_pack("1", "1;IR", b'\xaa', X,0,X,0,X,0,X,0)
+
+        self.assert_pack("1", "L", b'\xff\x00\x00\xff\x00\x00', X,0,0,X,0,0)
+
+    def test_L(self):
+        self.assert_pack("L", "L", 1, 1,2,3,4)
+
+    def test_LA(self):
+        self.assert_pack("LA", "LA", 2, (1,2), (3,4), (5,6))
+        self.assert_pack("LA", "LA;L", 2, (1,4), (2,5), (3,6))
+
+    def test_P(self):
+        self.assert_pack("P", "P;1", b'\xe4', 1, 1, 1, 0, 0, 255, 0, 0)
+        self.assert_pack("P", "P;2", b'\xe4', 3, 2, 1, 0)
+        self.assert_pack("P", "P;4", b'\x02\xef', 0, 2, 14, 15)
+        self.assert_pack("P", "P", 1, 1, 2, 3, 4)
+
+    def test_PA(self):
+        self.assert_pack("PA", "PA", 2, (1,2), (3,4), (5,6))
+        self.assert_pack("PA", "PA;L", 2, (1,4), (2,5), (3,6))
+
+    def test_RGB(self):
+        self.assert_pack("RGB", "RGB", 3, (1,2,3), (4,5,6), (7,8,9))
+        self.assert_pack("RGB", "RGBX",
+            b'\x01\x02\x03\xff\x05\x06\x07\xff', (1,2,3), (5,6,7))
+        self.assert_pack("RGB", "XRGB",
+            b'\x00\x02\x03\x04\x00\x06\x07\x08', (2,3,4), (6,7,8))
+        self.assert_pack("RGB", "BGR", 3, (3,2,1), (6,5,4), (9,8,7))
+        self.assert_pack("RGB", "BGRX",
+            b'\x01\x02\x03\x00\x05\x06\x07\x00', (3,2,1), (7,6,5))
+        self.assert_pack("RGB", "XBGR",
+            b'\x00\x02\x03\x04\x00\x06\x07\x08', (4,3,2), (8,7,6))
+        self.assert_pack("RGB", "RGB;L", 3, (1,4,7), (2,5,8), (3,6,9))
+        self.assert_pack("RGB", "R", 1, (1,9,9), (2,9,9), (3,9,9))
+        self.assert_pack("RGB", "G", 1, (9,1,9), (9,2,9), (9,3,9))
+        self.assert_pack("RGB", "B", 1, (9,9,1), (9,9,2), (9,9,3))
+
+    def test_RGBA(self):
+        self.assert_pack("RGBA", "RGBA", 4,
+            (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_pack("RGBA", "RGBA;L", 4,
+            (1,4,7,10), (2,5,8,11), (3,6,9,12))
+        self.assert_pack("RGBA", "RGB", 3, (1,2,3,14), (4,5,6,15), (7,8,9,16))
+        self.assert_pack("RGBA", "BGR", 3, (3,2,1,14), (6,5,4,15), (9,8,7,16))
+        self.assert_pack("RGBA", "BGRA", 4,
+            (3,2,1,4), (7,6,5,8), (11,10,9,12))
+        self.assert_pack("RGBA", "ABGR", 4,
+            (4,3,2,1), (8,7,6,5), (12,11,10,9))
+        self.assert_pack("RGBA", "BGRa", 4,
+            (191,127,63,4), (223,191,159,8), (233,212,191,12))
+        self.assert_pack("RGBA", "R", 1, (1,0,8,9), (2,0,8,9), (3,0,8,0))
+        self.assert_pack("RGBA", "G", 1, (6,1,8,9), (6,2,8,9), (6,3,8,9))
+        self.assert_pack("RGBA", "B", 1, (6,7,1,9), (6,7,2,0), (6,7,3,9))
+        self.assert_pack("RGBA", "A", 1, (6,7,0,1), (6,7,0,2), (0,7,0,3))
+
+    def test_RGBa(self):
+        self.assert_pack("RGBa", "RGBa", 4,
+            (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_pack("RGBa", "BGRa", 4,
+            (3,2,1,4), (7,6,5,8), (11,10,9,12))
+        self.assert_pack("RGBa", "aBGR", 4,
+            (4,3,2,1), (8,7,6,5), (12,11,10,9))
+
+    def test_RGBX(self):
+        self.assert_pack("RGBX", "RGBX", 4, (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_pack("RGBX", "RGBX;L", 4, (1,4,7,10), (2,5,8,11), (3,6,9,12))
+        self.assert_pack("RGBX", "RGB", 3, (1,2,3,X), (4,5,6,X), (7,8,9,X))
+        self.assert_pack("RGBX", "BGR", 3, (3,2,1,X), (6,5,4,X), (9,8,7,X))
+        self.assert_pack("RGBX", "BGRX",
+            b'\x01\x02\x03\x00\x05\x06\x07\x00\t\n\x0b\x00',
+            (3,2,1,X), (7,6,5,X), (11,10,9,X))
+        self.assert_pack("RGBX", "XBGR",
+            b'\x00\x02\x03\x04\x00\x06\x07\x08\x00\n\x0b\x0c',
+            (4,3,2,X), (8,7,6,X), (12,11,10,X))
+        self.assert_pack("RGBX", "R", 1, (1,0,8,9), (2,0,8,9), (3,0,8,0))
+        self.assert_pack("RGBX", "G", 1, (6,1,8,9), (6,2,8,9), (6,3,8,9))
+        self.assert_pack("RGBX", "B", 1, (6,7,1,9), (6,7,2,0), (6,7,3,9))
+        self.assert_pack("RGBX", "X", 1, (6,7,0,1), (6,7,0,2), (0,7,0,3))
+
 
 class TestLibUnpack(PillowTestCase):
     def assert_unpack(self, mode, rawmode, data, *pixels):
diff --git a/libImaging/Pack.c b/libImaging/Pack.c
index 621936351..0810f51f1 100644
--- a/libImaging/Pack.c
+++ b/libImaging/Pack.c
@@ -559,8 +559,8 @@ static struct {
     /* true colour w. padding */
     {"RGBX",    "RGBX",         32,     copy4},
     {"RGBX",    "RGBX;L",       32,     packRGBXL},
-    {"RGBX",    "RGB",          32,     ImagingPackRGB},
-    {"RGBX",    "BGR",          32,     ImagingPackBGR},
+    {"RGBX",    "RGB",          24,     ImagingPackRGB},
+    {"RGBX",    "BGR",          24,     ImagingPackBGR},
     {"RGBX",    "BGRX",         32,     ImagingPackBGRX},
     {"RGBX",    "XBGR",         32,     ImagingPackXBGR},
     {"RGBX",    "R",            8,      band0},

From ebb10e8e1a2c87ca9e0ea608a659ca080adad33f Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Thu, 24 Aug 2017 01:45:24 +0300
Subject: [PATCH 12/14] Fix error in pypy

---
 PIL/PyAccess.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/PIL/PyAccess.py b/PIL/PyAccess.py
index d5acfd0fe..09ce86af4 100644
--- a/PIL/PyAccess.py
+++ b/PIL/PyAccess.py
@@ -133,6 +133,7 @@ class _PyAccess32_3(PyAccess):
         pixel.r = min(color[0], 255)
         pixel.g = min(color[1], 255)
         pixel.b = min(color[2], 255)
+        pixel.a = 255
 
 
 class _PyAccess32_4(PyAccess):

From f43b9f396f628e1377516ea17ac63453ca4de530 Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Sat, 26 Aug 2017 10:49:28 +0300
Subject: [PATCH 13/14] Second part of pack tests

---
 Tests/test_lib_pack.py | 90 ++++++++++++++++++++++++++++++------------
 libImaging/Pack.c      |  4 +-
 2 files changed, 67 insertions(+), 27 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index d26a18d2e..b23ae58af 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -9,32 +9,9 @@ X = 255
 
 
 class TestLibPack(PillowTestCase):
-    def test_pack(self):
-
-        def pack(mode, rawmode, in_data=(1, 2, 3, 4)):
-            if len(mode) == 1:
-                im = Image.new(mode, (1, 1), in_data[0])
-            else:
-                im = Image.new(mode, (1, 1), in_data[:len(mode)])
-
-            if py3:
-                return list(im.tobytes("raw", rawmode))
-            else:
-                return [ord(c) for c in im.tobytes("raw", rawmode)]
-
-        order = 1 if Image._ENDIAN == '<' else -1
-
-
-        self.assertEqual(pack("I", "I"), [1, 0, 0, 0][::order])
-
-        self.assertEqual(pack("F", "F"), [0, 0, 128, 63][::order])
-
-        self.assertEqual(pack("CMYK", "CMYK"), [1, 2, 3, 4])
-        self.assertEqual(pack("YCbCr", "YCbCr"), [1, 2, 3])
-
     def assert_pack(self, mode, rawmode, data, *pixels):
         """
-        data - eather raw bytes with data or just number of bytes in rawmode.
+        data - either raw bytes with data or just number of bytes in rawmode.
         """
         im = Image.new(mode, (len(pixels), 1))
         for x, pixel in enumerate(pixels):
@@ -134,11 +111,74 @@ class TestLibPack(PillowTestCase):
         self.assert_pack("RGBX", "B", 1, (6,7,1,9), (6,7,2,0), (6,7,3,9))
         self.assert_pack("RGBX", "X", 1, (6,7,0,1), (6,7,0,2), (0,7,0,3))
 
+    def test_CMYK(self):
+        self.assert_pack("CMYK", "CMYK", 4, (1,2,3,4), (5,6,7,8), (9,10,11,12))
+        self.assert_pack("CMYK", "CMYK;I", 4,
+            (254,253,252,251), (250,249,248,247), (246,245,244,243))
+        self.assert_pack("CMYK", "CMYK;L", 4,
+            (1,4,7,10), (2,5,8,11), (3,6,9,12))
+        self.assert_pack("CMYK", "K", 1, (6,7,0,1), (6,7,0,2), (0,7,0,3))
+
+    def test_YCbCr(self):
+        self.assert_pack("YCbCr", "YCbCr", 3, (1,2,3), (4,5,6), (7,8,9))
+        self.assert_pack("YCbCr", "YCbCr;L", 3, (1,4,7), (2,5,8), (3,6,9))
+        self.assert_pack("YCbCr", "YCbCrX",
+            '\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff',
+            (1,2,3), (5,6,7), (9,10,11))
+        self.assert_pack("YCbCr", "YCbCrK",
+            '\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff',
+            (1,2,3), (5,6,7), (9,10,11))
+        self.assert_pack("YCbCr", "Y", 1, (1,0,8,9), (2,0,8,9), (3,0,8,0))
+        self.assert_pack("YCbCr", "Cb", 1, (6,1,8,9), (6,2,8,9), (6,3,8,9))
+        self.assert_pack("YCbCr", "Cr", 1, (6,7,1,9), (6,7,2,0), (6,7,3,9))
+
+    def test_LAB(self):
+        self.assert_pack("LAB", "LAB", 3,
+            (1,130,131), (4,133,134), (7,136,137))
+        self.assert_pack("LAB", "L", 1, (1,9,9), (2,9,9), (3,9,9))
+        self.assert_pack("LAB", "A", 1, (9,1,9), (9,2,9), (9,3,9))
+        self.assert_pack("LAB", "B", 1, (9,9,1), (9,9,2), (9,9,3))
+
+    def test_HSV(self):
+        self.assert_pack("HSV", "HSV", 3, (1,2,3), (4,5,6), (7,8,9))
+        self.assert_pack("HSV", "H", 1, (1,9,9), (2,9,9), (3,9,9))
+        self.assert_pack("HSV", "S", 1, (9,1,9), (9,2,9), (9,3,9))
+        self.assert_pack("HSV", "V", 1, (9,9,1), (9,9,2), (9,9,3))
+
+    def test_I(self):
+        self.assert_pack("I", "I", 4, 0x04030201, 0x08070605)
+        self.assert_pack("I", "I;16B", 2, 0x0102, 0x0304)
+        self.assert_pack("I", "I;32S",
+            b'\x83\x00\x00\x01\x01\x00\x00\x83',
+            0x01000083, -2097151999)
+
+        if sys.byteorder == 'little':
+            self.assert_pack("I", "I;32NS",
+                b'\x83\x00\x00\x01\x01\x00\x00\x83',
+                0x01000083, -2097151999)
+        else:
+            self.assert_pack("I", "I;32NS",
+                b'\x83\x00\x00\x01\x01\x00\x00\x83',
+                -2097151999, 0x01000083)
+
+    def test_F_float(self):
+        self.assert_pack("F", "F", 4,
+            1.539989614439558e-36, 4.063216068939723e-34)
+        self.assert_pack("F", "F;32F", 4,
+            1.539989614439558e-36, 4.063216068939723e-34)
+
+        if sys.byteorder == 'little':
+            self.assert_pack("F", "F;32NF", 4,
+                1.539989614439558e-36, 4.063216068939723e-34)
+        else:
+            self.assert_pack("F", "F;32NF", 4,
+                2.387939260590663e-38, 6.301941157072183e-36)
+
 
 class TestLibUnpack(PillowTestCase):
     def assert_unpack(self, mode, rawmode, data, *pixels):
         """
-        data - eather raw bytes with data or just number of bytes in rawmode.
+        data - either raw bytes with data or just number of bytes in rawmode.
         """
         if isinstance(data, (int)):
             data_len = data * len(pixels)
diff --git a/libImaging/Pack.c b/libImaging/Pack.c
index 0810f51f1..b9d1d6a2a 100644
--- a/libImaging/Pack.c
+++ b/libImaging/Pack.c
@@ -599,13 +599,13 @@ static struct {
     {"HSV",     "V",           8,      band2},
 
     /* integer */
-    {"I",       "I",            32,     copy4},
+    {"I",       "I",            32,     packI32S},
     {"I",       "I;16B",        16,     packI16B},
     {"I",       "I;32S",        32,     packI32S},
     {"I",       "I;32NS",       32,     copy4},
 
     /* floating point */
-    {"F",       "F",            32,     copy4},
+    {"F",       "F",            32,     packI32S},
     {"F",       "F;32F",        32,     packI32S},
     {"F",       "F;32NF",       32,     copy4},
 

From 922407e7f3e6a9820e0e536d5d761ca3d2bca960 Mon Sep 17 00:00:00 2001
From: Alexander <homm86@gmail.com>
Date: Sat, 26 Aug 2017 11:02:51 +0300
Subject: [PATCH 14/14] fix py3, change test

---
 Tests/test_lib_pack.py | 4 ++--
 Tests/test_mode_i16.py | 4 +---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/Tests/test_lib_pack.py b/Tests/test_lib_pack.py
index b23ae58af..b4c8b6a56 100644
--- a/Tests/test_lib_pack.py
+++ b/Tests/test_lib_pack.py
@@ -123,10 +123,10 @@ class TestLibPack(PillowTestCase):
         self.assert_pack("YCbCr", "YCbCr", 3, (1,2,3), (4,5,6), (7,8,9))
         self.assert_pack("YCbCr", "YCbCr;L", 3, (1,4,7), (2,5,8), (3,6,9))
         self.assert_pack("YCbCr", "YCbCrX",
-            '\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff',
+            b'\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff',
             (1,2,3), (5,6,7), (9,10,11))
         self.assert_pack("YCbCr", "YCbCrK",
-            '\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff',
+            b'\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff',
             (1,2,3), (5,6,7), (9,10,11))
         self.assert_pack("YCbCr", "Y", 1, (1,0,8,9), (2,0,8,9), (3,0,8,0))
         self.assert_pack("YCbCr", "Cb", 1, (6,1,8,9), (6,2,8,9), (6,3,8,9))
diff --git a/Tests/test_mode_i16.py b/Tests/test_mode_i16.py
index d51847199..53bbce572 100644
--- a/Tests/test_mode_i16.py
+++ b/Tests/test_mode_i16.py
@@ -87,12 +87,10 @@ class TestModeI16(PillowTestCase):
         def tobytes(mode):
             return Image.new(mode, (1, 1), 1).tobytes()
 
-        order = 1 if Image._ENDIAN == '<' else -1
-
         self.assertEqual(tobytes("L"), b"\x01")
         self.assertEqual(tobytes("I;16"), b"\x01\x00")
         self.assertEqual(tobytes("I;16B"), b"\x00\x01")
-        self.assertEqual(tobytes("I"), b"\x01\x00\x00\x00"[::order])
+        self.assertEqual(tobytes("I"), b"\x01\x00\x00\x00")
 
     def test_convert(self):