From 73839c499a6e2b9dd42b49b2e60432ddf663afd8 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Dec 2024 18:01:55 +0100 Subject: [PATCH] PNG: fix reading 16-bit interlaced images (on little-endian machines) Fixes https://lists.osgeo.org/pipermail/gdal-dev/2024-December/059989.html --- autotest/gdrivers/data/png/uint16_interlaced.png | Bin 0 -> 775 bytes autotest/gdrivers/png.py | 10 ++++++++++ frmts/png/pngdataset.cpp | 15 +++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 autotest/gdrivers/data/png/uint16_interlaced.png diff --git a/autotest/gdrivers/data/png/uint16_interlaced.png b/autotest/gdrivers/data/png/uint16_interlaced.png new file mode 100644 index 0000000000000000000000000000000000000000..a8888de766b77915f0745bf178f1c8edc201bd69 GIT binary patch literal 775 zcmeAS@N?(olHy`uVBq!ia0vp^A|NaPBpCZk*RcR;mUKs7M+SzC{oH>NS%G|}ByV?@ z|Nli+8=eL7*h@TpUD=;AbBl?oEaloao+TjZI?)(245IleYE zt~;=xMex=cHdfwhPPL}ZEQdLLkEhPq!EUaQv7*tDT{vVx059JaX6aX~suDhxm#fb| z{B!3}^xU0S7HPiaZ9CMv(d6_}b&))Sn?Iv&%}TxhrB(Xig3X$Sx14z0+=DX(-mvIv zhjYyropxyJITa=8QZ=sln(4ARE|O=ax^Ie>o;!b$y;v5bW6>2U*2q;~<0|zz7I{u; zIb&@}1ww|EsS+u~w`p1H+FM8E9V!GYdo=bQ>``m(~f%$Qz zym2AxQcT~uaGu<`W?O`fNrX%H{-tZz&h^W`q?CQ3LQ9f0uq<_rO?kKDl({E2xtjcZ zdS~u6{c8EEQ}-U@-z%Thy=1aZ_5*RT?)!Q+D{LmuwcfR5&9{2%&E?wGCpU3#4t~0I z|G7B@B|<9wcUPuP7xT=&mYF4Zu;xC)Hoho!8J4{#J7Q*ioisO0eY4(;7r7fZ3okvi zeCv_wedo&8I>ww|yI$fSuFemrf*-CTH7_MIF^?gqI4N|yxHC{n7A{qgkzbOZn_5zonaq%z znWvjstecdRn4E33f0q%8Ek*g|#kvKlMY_d6wFN-uWknaV0aY+~y85}Sb4q9e09KAF A0RR91 literal 0 HcmV?d00001 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)