Thanks to visit codestin.com
Credit goes to github.com

Skip to content

_png extension loads 16-bit PNGs as 8-bit #915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 5, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/matplotlib/testing/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions lib/matplotlib/tests/test_png.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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/uint16.png'))

assert (img.dtype == np.uint16)
assert np.sum(img.flatten()) == 134184960
54 changes: 45 additions & 9 deletions src/_png.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand All @@ -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, int result_bit_depth = -1);
};

static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length)
Expand Down Expand Up @@ -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,
int result_bit_depth)
{
png_byte header[8]; // 8 is the maximum size that can be checked
FILE* fp = NULL;
Expand Down Expand Up @@ -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 < 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 {
throw Py::RuntimeError(
"_image_module::readpng: image has unknown bit depth");
}

if (A == NULL)
{
Expand All @@ -518,17 +533,32 @@ _png_module::_read_png(const Py::Object& py_fileobj, const bool float_result)
if (bit_depth == 16)
{
png_uint_16* ptr = &reinterpret_cast<png_uint_16*>(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 (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] >> 8;
}
}
}
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];
}
}
}
}
Expand Down Expand Up @@ -569,6 +599,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));
Expand Down