From 0e4f3ccbffe67d8ef00771ed37567f1f9c3a244c Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 1 Jun 2012 12:18:49 -0400 Subject: [PATCH 1/2] Add 16-bit PNG support to _png module. --- lib/matplotlib/testing/compare.py | 4 +- .../test_png/pngtest16rgba.png | Bin 0 -> 3435 bytes lib/matplotlib/tests/test_png.py | 10 +++++ src/_png.cpp | 41 +++++++++++++++--- 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_png/pngtest16rgba.png diff --git a/lib/matplotlib/testing/compare.py b/lib/matplotlib/testing/compare.py index bd2184c62ed0..c39b6e082102 100644 --- a/lib/matplotlib/testing/compare.py +++ b/lib/matplotlib/testing/compare.py @@ -210,8 +210,8 @@ def compare_images( expected, actual, tol, in_decorator=False ): expected = convert(expected) # open the image files and remove the alpha channel (if it exists) - expectedImage = _png.read_png_uint8( expected ) - actualImage = _png.read_png_uint8( actual ) + expectedImage = _png.read_png_int( expected ) + actualImage = _png.read_png_int( actual ) actualImage, expectedImage = crop_to_same(actual, actualImage, expected, expectedImage) diff --git a/lib/matplotlib/tests/baseline_images/test_png/pngtest16rgba.png b/lib/matplotlib/tests/baseline_images/test_png/pngtest16rgba.png new file mode 100644 index 0000000000000000000000000000000000000000..984a99525f5246cbc5d7083dd79006c7efa0ab0b GIT binary patch literal 3435 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 AY5)KL literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_png.py b/lib/matplotlib/tests/test_png.py index 516001ca3298..e35d225c297b 100644 --- a/lib/matplotlib/tests/test_png.py +++ b/lib/matplotlib/tests/test_png.py @@ -3,6 +3,7 @@ import matplotlib.cm as cm import glob import os +import numpy as np @image_comparison(baseline_images=['pngsuite'], extensions=['png']) def test_pngsuite(): @@ -25,3 +26,12 @@ def test_pngsuite(): plt.gca().get_frame().set_facecolor("#ddffff") plt.gca().set_xlim(0, len(files)) + + +def test_imread_png_uint16(): + from matplotlib import _png + img = _png.read_png_int(os.path.join(os.path.dirname(__file__), + 'baseline_images/test_png/pngtest16rgba.png')) + assert (img.dtype == np.uint16) + + assert np.sum(img.flatten()) == 104855776 diff --git a/src/_png.cpp b/src/_png.cpp index 2166d6406d9e..8ddfcc6a5dec 100644 --- a/src/_png.cpp +++ b/src/_png.cpp @@ -48,6 +48,8 @@ class _png_module : public Py::ExtensionModule<_png_module> "read_png_float(fileobj)"); add_varargs_method("read_png_uint8", &_png_module::read_png_uint8, "read_png_uint8(fileobj)"); + add_varargs_method("read_png_int", &_png_module::read_png_int, + "read_png_int(fileobj)"); initialize("Module to write PNG files"); } @@ -57,7 +59,8 @@ class _png_module : public Py::ExtensionModule<_png_module> Py::Object write_png(const Py::Tuple& args); Py::Object read_png_uint8(const Py::Tuple& args); Py::Object read_png_float(const Py::Tuple& args); - PyObject* _read_png(const Py::Object& py_fileobj, const bool float_result); + Py::Object read_png_int(const Py::Tuple& args); + PyObject* _read_png(const Py::Object& py_fileobj, const bool float_result, const int bit_depth = -1); }; static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length) @@ -297,7 +300,8 @@ static void read_png_data(png_structp png_ptr, png_bytep data, png_size_t length } PyObject* -_png_module::_read_png(const Py::Object& py_fileobj, const bool float_result) +_png_module::_read_png(const Py::Object& py_fileobj, const bool float_result, + const int result_bit_depth) { png_byte header[8]; // 8 is the maximum size that can be checked FILE* fp = NULL; @@ -502,7 +506,18 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result) } } } else { - A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE); + if (result_bit_depth == 8) { + A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE); + } else { + if (bit_depth == 8) { + A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE); + } else if (bit_depth == 16) { + A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UINT16); + } else { + throw Py::RuntimeError( + "_image_module::readpng: image has unknown bit depth"); + } + } if (A == NULL) { @@ -518,9 +533,17 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result) if (bit_depth == 16) { png_uint_16* ptr = &reinterpret_cast(row)[x * dimensions[2]]; - for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) - { - *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p] >> 8; + + if (bit_depth == 16) { + for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) + { + *(png_uint_16*)(A->data + offset + p*A->strides[2]) = ptr[p]; + } + } else { + for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) + { + *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p] >> 8; + } } } else @@ -569,6 +592,12 @@ _png_module::read_png_float(const Py::Tuple& args) Py::Object _png_module::read_png_uint8(const Py::Tuple& args) +{ + throw Py::RuntimeError("read_png_uint8 is deprecated. Use read_png_int instead."); +} + +Py::Object +_png_module::read_png_int(const Py::Tuple& args) { args.verify_length(1); return Py::asObject(_read_png(args[0], false)); From c2872fa483bb7ab9332e7947b2dd8fd74cc6222d Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 5 Jun 2012 14:43:47 -0400 Subject: [PATCH 2/2] Fix some problems in the last commit. Use a grayscale image, since multi-byte rgba is not supported by the image interpolation code. --- .../test_png/pngtest16rgba.png | Bin 3435 -> 0 bytes .../tests/baseline_images/test_png/uint16.png | Bin 0 -> 7433 bytes lib/matplotlib/tests/test_png.py | 6 +-- src/_png.cpp | 35 +++++++++++------- 4 files changed, 24 insertions(+), 17 deletions(-) delete mode 100644 lib/matplotlib/tests/baseline_images/test_png/pngtest16rgba.png create mode 100644 lib/matplotlib/tests/baseline_images/test_png/uint16.png diff --git a/lib/matplotlib/tests/baseline_images/test_png/pngtest16rgba.png b/lib/matplotlib/tests/baseline_images/test_png/pngtest16rgba.png deleted file mode 100644 index 984a99525f5246cbc5d7083dd79006c7efa0ab0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3435 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 AY5)KL diff --git a/lib/matplotlib/tests/baseline_images/test_png/uint16.png b/lib/matplotlib/tests/baseline_images/test_png/uint16.png new file mode 100644 index 0000000000000000000000000000000000000000..9afca6989287415e4dc7d23ba7836174fa568c28 GIT binary patch literal 7433 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 O*jRwf+fDy_@P7a|bD!J* literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_png.py b/lib/matplotlib/tests/test_png.py index e35d225c297b..9cdee17738cf 100644 --- a/lib/matplotlib/tests/test_png.py +++ b/lib/matplotlib/tests/test_png.py @@ -31,7 +31,7 @@ def test_pngsuite(): def test_imread_png_uint16(): from matplotlib import _png img = _png.read_png_int(os.path.join(os.path.dirname(__file__), - 'baseline_images/test_png/pngtest16rgba.png')) - assert (img.dtype == np.uint16) + 'baseline_images/test_png/uint16.png')) - assert np.sum(img.flatten()) == 104855776 + assert (img.dtype == np.uint16) + assert np.sum(img.flatten()) == 134184960 diff --git a/src/_png.cpp b/src/_png.cpp index 8ddfcc6a5dec..23ee5980b79a 100644 --- a/src/_png.cpp +++ b/src/_png.cpp @@ -60,7 +60,7 @@ class _png_module : public Py::ExtensionModule<_png_module> Py::Object read_png_uint8(const Py::Tuple& args); Py::Object read_png_float(const Py::Tuple& args); Py::Object read_png_int(const Py::Tuple& args); - PyObject* _read_png(const Py::Object& py_fileobj, const bool float_result, const int bit_depth = -1); + PyObject* _read_png(const Py::Object& py_fileobj, const bool float_result, int result_bit_depth = -1); }; static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length) @@ -301,7 +301,7 @@ static void read_png_data(png_structp png_ptr, png_bytep data, png_size_t length PyObject* _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result, - const int result_bit_depth) + int result_bit_depth) { png_byte header[8]; // 8 is the maximum size that can be checked FILE* fp = NULL; @@ -506,17 +506,17 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result, } } } else { + if (result_bit_depth < 0) { + result_bit_depth = bit_depth; + } + if (result_bit_depth == 8) { A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE); + } else if (result_bit_depth == 16) { + A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UINT16); } else { - if (bit_depth == 8) { - A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE); - } else if (bit_depth == 16) { - A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UINT16); - } else { - throw Py::RuntimeError( - "_image_module::readpng: image has unknown bit depth"); - } + throw Py::RuntimeError( + "_image_module::readpng: image has unknown bit depth"); } if (A == NULL) @@ -534,7 +534,7 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result, { png_uint_16* ptr = &reinterpret_cast(row)[x * dimensions[2]]; - if (bit_depth == 16) { + if (result_bit_depth == 16) { for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) { *(png_uint_16*)(A->data + offset + p*A->strides[2]) = ptr[p]; @@ -549,9 +549,16 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result, else { png_byte* ptr = &(row[x * dimensions[2]]); - for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) - { - *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p]; + if (result_bit_depth == 16) { + for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) + { + *(png_uint_16*)(A->data + offset + p*A->strides[2]) = ptr[p]; + } + } else { + for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) + { + *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p]; + } } } }