".github/git@developer.sourcefind.cn:OpenDAS/bitsandbytes.git" did not exist on "9f85829479ac2299dcf692e913a83911a1069ad4"
Unverified Commit e1f22ed1 authored by Vincent Moens's avatar Vincent Moens Committed by GitHub
Browse files

deinterlacing PNG images with read_image (#4268)



* interlaced png images
Co-authored-by: default avatarVincent Moens <vmoens@fb.com>
parent 7de62659
...@@ -20,6 +20,7 @@ FAKEDATA_DIR = os.path.join(IMAGE_ROOT, "fakedata") ...@@ -20,6 +20,7 @@ FAKEDATA_DIR = os.path.join(IMAGE_ROOT, "fakedata")
IMAGE_DIR = os.path.join(FAKEDATA_DIR, "imagefolder") IMAGE_DIR = os.path.join(FAKEDATA_DIR, "imagefolder")
DAMAGED_JPEG = os.path.join(IMAGE_ROOT, 'damaged_jpeg') DAMAGED_JPEG = os.path.join(IMAGE_ROOT, 'damaged_jpeg')
ENCODE_JPEG = os.path.join(IMAGE_ROOT, "encode_jpeg") ENCODE_JPEG = os.path.join(IMAGE_ROOT, "encode_jpeg")
INTERLACED_PNG = os.path.join(IMAGE_ROOT, "interlaced_png")
IS_WINDOWS = sys.platform in ('win32', 'cygwin') IS_WINDOWS = sys.platform in ('win32', 'cygwin')
PILLOW_VERSION = tuple(int(x) for x in PILLOW_VERSION.split('.')) PILLOW_VERSION = tuple(int(x) for x in PILLOW_VERSION.split('.'))
...@@ -304,6 +305,15 @@ def test_read_1_bit_png_consistency(shape, mode): ...@@ -304,6 +305,15 @@ def test_read_1_bit_png_consistency(shape, mode):
assert_equal(img1, img2) assert_equal(img1, img2)
def test_read_interlaced_png():
imgs = list(get_images(INTERLACED_PNG, ".png"))
with Image.open(imgs[0]) as im1, Image.open(imgs[1]) as im2:
assert not (im1.info.get("interlace") is im2.info.get("interlace"))
img1 = read_image(imgs[0])
img2 = read_image(imgs[1])
assert_equal(img1, img2)
@needs_cuda @needs_cuda
@pytest.mark.parametrize('img_path', [ @pytest.mark.parametrize('img_path', [
pytest.param(jpeg_path, id=_get_safe_image_name(jpeg_path)) pytest.param(jpeg_path, id=_get_safe_image_name(jpeg_path))
......
...@@ -55,6 +55,7 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) { ...@@ -55,6 +55,7 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) {
png_uint_32 width, height; png_uint_32 width, height;
int bit_depth, color_type; int bit_depth, color_type;
int interlace_type;
auto retval = png_get_IHDR( auto retval = png_get_IHDR(
png_ptr, png_ptr,
info_ptr, info_ptr,
...@@ -62,7 +63,7 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) { ...@@ -62,7 +63,7 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) {
&height, &height,
&bit_depth, &bit_depth,
&color_type, &color_type,
nullptr, &interlace_type,
nullptr, nullptr,
nullptr); nullptr);
...@@ -81,6 +82,13 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) { ...@@ -81,6 +82,13 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) {
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png_ptr); png_set_expand_gray_1_2_4_to_8(png_ptr);
int number_of_passes;
if (interlace_type == PNG_INTERLACE_ADAM7) {
number_of_passes = png_set_interlace_handling(png_ptr);
} else {
number_of_passes = 1;
}
if (mode != IMAGE_READ_MODE_UNCHANGED) { if (mode != IMAGE_READ_MODE_UNCHANGED) {
// TODO: consider supporting PNG_INFO_tRNS // TODO: consider supporting PNG_INFO_tRNS
bool is_palette = (color_type & PNG_COLOR_MASK_PALETTE) != 0; bool is_palette = (color_type & PNG_COLOR_MASK_PALETTE) != 0;
...@@ -163,9 +171,12 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) { ...@@ -163,9 +171,12 @@ torch::Tensor decode_png(const torch::Tensor& data, ImageReadMode mode) {
auto tensor = auto tensor =
torch::empty({int64_t(height), int64_t(width), channels}, torch::kU8); torch::empty({int64_t(height), int64_t(width), channels}, torch::kU8);
auto ptr = tensor.accessor<uint8_t, 3>().data(); auto ptr = tensor.accessor<uint8_t, 3>().data();
for (png_uint_32 i = 0; i < height; ++i) { for (int pass = 0; pass < number_of_passes; pass++) {
png_read_row(png_ptr, ptr, nullptr); for (png_uint_32 i = 0; i < height; ++i) {
ptr += width * channels; png_read_row(png_ptr, ptr, nullptr);
ptr += width * channels;
}
ptr = tensor.accessor<uint8_t, 3>().data();
} }
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
return tensor.permute({2, 0, 1}); return tensor.permute({2, 0, 1});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment