diff --git a/autotest/gdrivers/data/png/uint16_interlaced.png b/autotest/gdrivers/data/png/uint16_interlaced.png new file mode 100644 index 000000000000..a8888de766b7 Binary files /dev/null and b/autotest/gdrivers/data/png/uint16_interlaced.png differ diff --git a/autotest/gdrivers/png.py b/autotest/gdrivers/png.py index 7260ec251484..70c1688806aa 100755 --- a/autotest/gdrivers/png.py +++ b/autotest/gdrivers/png.py @@ -471,3 +471,13 @@ def test_png_copy_mdd(): ds = None gdal.Unlink(filename) + + +############################################################################### +# Read test of 16-bit interlaced + + +def test_png_read_interlace_16_bit(): + + ds = gdal.Open("data/png/uint16_interlaced.png") + assert ds.GetRasterBand(1).Checksum() == 4672 diff --git a/frmts/png/pngdataset.cpp b/frmts/png/pngdataset.cpp index 1f1fe174730b..cfe5981879c6 100644 --- a/frmts/png/pngdataset.cpp +++ b/frmts/png/pngdataset.cpp @@ -1405,6 +1405,21 @@ CPLErr PNGDataset::LoadInterlacedChunk(int iLine) bool bRet = safe_png_read_image(hPNG, png_rows, sSetJmpContext); + // Do swap on LSB machines. 16-bit PNG data is stored in MSB format. +#ifdef CPL_LSB + if (bRet && nBitDepth == 16) + { + for (int i = 0; i < GetRasterYSize(); i++) + { + if (i >= nBufferStartLine && i < nBufferStartLine + nBufferLines) + { + GDALSwapWords(png_rows[i], 2, + GetRasterXSize() * GetRasterCount(), 2); + } + } + } +#endif + CPLFree(png_rows); CPLFree(dummy_row); if (!bRet)