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

Add check for order of tile parts #118

Closed bitsgalore closed 4 years ago

bitsgalore commented 5 years ago

Section A.4.2 of ISO/IEC 15444-1 states:

A.4.2 Start of tile-part (SOT) Function: Marks the beginning of a tile-part, the index of its tile, and the index of its tile-part. The tile-parts of a given tile shall appear in order (see TPsot) in the codestream. However, tile-parts from other tiles may be interleaved in the codestream. Therefore, the tile-parts from a given tile may not appear contiguously in the codestream.

Jpylyzer currently doesn't check for this. However, if the tile parts are in the wrong order, some decoders (e.g. OpenJPEG) will be completely unable to read the image.

bitsgalore commented 5 years ago

Update: example of affected image:

http://resolver.kb.nl/resolve?urn=dts%3A2740001%3Ampeg21%3A0029%3Aimage

Reported errors:

<tests>
    <jp2HeaderBox>
        <colourSpecificationBox>
            <methIsValid>False</methIsValid>
            <precIsValid>False</precIsValid>
            <approxIsValid>False</approxIsValid>
        </colourSpecificationBox>
    </jp2HeaderBox>
    <contiguousCodestreamBox>
        <foundExpectedNumberOfTileParts>False</foundExpectedNumberOfTileParts>
        <tileParts>
            <tilePart>
                <foundSODMarker>False</foundSODMarker>
            </tilePart>
        </tileParts>
    </contiguousCodestreamBox>
</tests>

So the REAL issue here appears to be corrupted data somewhere in the SOT marker (note the foundSODMarker error. This is confirmed by looking at the tilePart properties, which contains this:

<tilePart>
    <sot>
        <lsot>10</lsot>
        <isot>7</isot>
        <psot>65538</psot>
        <tpsot>149</tpsot>
        <tnsot>108</tnsot>
    </sot>
</tilePart>

Note the ridiculously large values for tpsot and tnsot, with tpsot even being larger than tnsot (tnsot, the number of within-tile tile parts is 5 for all other tile parts). Needs further investigation, but at first sight it looks like the real problem here is that some of the data within this tile part are corrupted (which leads to the nonsense tpsot/tnsot values and the missing SOD marker), and NOT the order of the tile parts (this is a secondary problem that is caused by the corruption).

Having said that, an additional check on the tile-part order could still be useful, perhaps with an additional check to verify that:

if  tnsot != 0:
    tpsot < tnsot (note that first tile part has index 0!)