openpreserve / jpylyzer

JP2 (JPEG 2000 Part 1) validator and properties extractor. Jpylyzer was specifically created to check that a JP2 file really conforms to the format's specifications. Additionally jpylyzer is able to extract technical characteristics.
http://jpylyzer.openpreservation.org/
Other
69 stars 28 forks source link

Adobe Photoshop images with erroneous tile-part information no longer result in validation error #226

Closed bitsgalore closed 3 months ago

bitsgalore commented 3 months ago

See:

http://web.archive.org/web/20231001094926/https://wiki.opf-labs.org/display/TR/Erroneous+tile-part+information+in+images+created+by+Adobe+Photoshop

Test "foundExpectedNumberOfTileParts" no longer fails. Not entirely sure if this is a regression, or perhaps these images were never faulty to begin with.

For both example images mentioned there, tnsot (number of tile parts per tile) equals 5, but tpsot varies from 0 to 5 (indicating 6 tile parts):

                <tilePart>
                    <sot>
                        <lsot>10</lsot>
                        <isot>4</isot>
                        <psot>48646</psot>
                        <tpsot>5</tpsot>
                        <tnsot>5</tnsot>
                    </sot>
                    <pltCount>0</pltCount>
                    <pptCount>0</pptCount>
                </tilePart>
bitsgalore commented 3 months ago

This affects the following test:

            self.testFor("foundExpectedNumberOfTileParts",
                         len(set(tilePartsPerTileExpected.items())) in
                         [len(set(tilePartsPerTileFound.items())), 0])

For file balloon_eciRGBv2_ps_adobeplugin.jpf:

tilePartsPerTileExpected = {0: 5, 1: 5, 2: 5, 3: 5, 4: 5, 5: 5, 6: 5, 7: 5, 8: 5, 9: 5, 10: 5, 11: 5}

and

tilePartsPerTileFound = {0: 6, 1: 6, 2: 6, 3: 6, 4: 6, 5: 6, 6: 6, 7: 6, 8: 6, 9: 6, 10: 6, 11: 6}

BUT these are dictionaries, and applying "set" to get (only) unique values only works for lists! For both of the above dictionaries "set results in:

{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}

So test should be changed to:

            # Found numbers of tile parts per tile must match expected
            self.testFor("foundExpectedNumberOfTileParts",
                         tilePartsPerTileExpected == tilePartsPerTileFound)

Fix:

https://github.com/openpreserve/jpylyzer/commit/b2089049f4886e6b69d6292af8561b9d35471b8e

Added test image:

https://github.com/openpreserve/jpylyzer-test-files/commit/0290e98bae9c5480c995954d3f14b4cf0a0395ff

Added test:

https://github.com/openpreserve/jpylyzer/commit/60325f2f86989544ff7e5afc3fe68d085db063e1

bitsgalore commented 3 months ago

UPDATE - after this change, several JP2 that only have one tile-part per tile now fail "foundExpectedNumberOfTileParts":

FAILED tests/unit/test_testfiles.py::test_validation_outcome_jp2[/home/johan/jpylyzer-test-files/files/erdas-sandiego3i_5.5.jp2]
FAILED tests/unit/test_testfiles.py::test_validation_outcome_jp2[/home/johan/jpylyzer-test-files/files/erdas-nullinput-uint8-rgb-null-2tileparts.jp2]
FAILED tests/unit/test_testfiles.py::test_validation_outcome_jp2[/home/johan/jpylyzer-test-files/files/erdas-sandiego1m_null.jp2]
FAILED tests/unit/test_testfiles.py::test_validation_outcome_jp2[/home/johan/jpylyzer-test-files/files/erdas-sandiego3i_5.2.jp2]
FAILED tests/unit/test_testfiles.py::test_validation_outcome_jp2[/home/johan/jpylyzer-test-files/files/oj-tnsot-0.jp2]

Fixed by additional check on whether number of expected tileparts is defined:

https://github.com/openpreserve/jpylyzer/commit/4fd7c23efa9de32d44f7c475509f60ca647aef5a