From 13eb3d667afb8df8b4ac9a68a4fb936b1f8f3e7e Mon Sep 17 00:00:00 2001 From: wiredfool Date: Tue, 29 Jul 2014 20:44:17 -0700 Subject: [PATCH] Added profile.tobytes() for ImageCms Profiles --- PIL/ImageCms.py | 2 ++ Tests/test_imagecms.py | 17 +++++++++++++++ _imagingcms.c | 47 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/PIL/ImageCms.py b/PIL/ImageCms.py index 4ea6409d6..9848e5ba2 100644 --- a/PIL/ImageCms.py +++ b/PIL/ImageCms.py @@ -169,6 +169,8 @@ class ImageCmsProfile: self.product_name = None self.product_info = None + def tobytes(self): + return core.profile_tobytes(self.profile) class ImageCmsTransform(Image.ImagePointHandler): diff --git a/Tests/test_imagecms.py b/Tests/test_imagecms.py index 152241f90..74eef3037 100644 --- a/Tests/test_imagecms.py +++ b/Tests/test_imagecms.py @@ -210,6 +210,23 @@ class TestImageCms(PillowTestCase): self.assert_image_similar(lena(), out, 2) + def test_profile_tobytes(self): + from io import BytesIO + i = Image.open("Tests/images/rgb.jpg") + p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) + + p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes())) + + # not the same bytes as the original icc_profile, + # but it does roundtrip + self.assertEqual(p.tobytes(),p2.tobytes()) + self.assertEqual(ImageCms.getProfileName(p), + ImageCms.getProfileName(p2)) + self.assertEqual(ImageCms.getProfileDescription(p), + ImageCms.getProfileDescription(p2)) + + + if __name__ == '__main__': unittest.main() diff --git a/_imagingcms.c b/_imagingcms.c index 1b7ef49e1..3b822006a 100644 --- a/_imagingcms.c +++ b/_imagingcms.c @@ -49,7 +49,8 @@ http://www.cazabon.com\n\ /* known to-do list with current version: - Verify that PILmode->littleCMStype conversion in findLCMStype is correct for all PIL modes (it probably isn't for the more obscure ones) + Verify that PILmode->littleCMStype conversion in findLCMStype is correct for all + PIL modes (it probably isn't for the more obscure ones) Add support for creating custom RGB profiles on the fly Add support for checking presence of a specific tag in a profile @@ -134,6 +135,49 @@ cms_profile_fromstring(PyObject* self, PyObject* args) return cms_profile_new(hProfile); } +static PyObject* +cms_profile_tobytes(PyObject* self, PyObject* args) +{ + char *pProfile =NULL; + cmsUInt32Number nProfile; + PyObject* CmsProfile; + + cmsHPROFILE *profile; + + PyObject* ret; + if (!PyArg_ParseTuple(args, "O", &CmsProfile)){ + return NULL; + } + + profile = ((CmsProfileObject*)CmsProfile)->profile; + + if (!cmsSaveProfileToMem(profile, pProfile, &nProfile)) { + PyErr_SetString(PyExc_IOError, "Could not determine profile size"); + return NULL; + } + + pProfile = (char*)malloc(nProfile); + if (!pProfile) { + PyErr_SetString(PyExc_IOError, "Out of Memory"); + return NULL; + } + + if (!cmsSaveProfileToMem(profile, pProfile, &nProfile)) { + PyErr_SetString(PyExc_IOError, "Could not get profile"); + free(pProfile); + return NULL; + } + +#if PY_VERSION_HEX >= 0x03000000 + ret = PyBytes_FromStringAndSize(pProfile, (Py_ssize_t)nProfile); +#else + ret = PyString_FromStringAndSize(pProfile, (Py_ssize_t)nProfile); +#endif + + free(pProfile); + return ret; +} + static void cms_profile_dealloc(CmsProfileObject* self) { @@ -485,6 +529,7 @@ static PyMethodDef pyCMSdll_methods[] = { {"profile_open", cms_profile_open, 1}, {"profile_frombytes", cms_profile_fromstring, 1}, {"profile_fromstring", cms_profile_fromstring, 1}, + {"profile_tobytes", cms_profile_tobytes, 1}, /* profile and transform functions */ {"buildTransform", buildTransform, 1},