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

Code related to quantization style, lqcd and levels in qcd/qcc validator needs overhaul #132

Closed bitsgalore closed 4 years ago

bitsgalore commented 4 years ago

Current code in qcd and qcc functions:

        # No. of decomposition levels --> cross-check with info from COD!!
        if qStyle == 0:
            levels = int((lqcd - 4) / 3)
        elif qStyle == 2:
            levels = int((lqcd - 5) / 6)

        # Check lqcd is consistent with levels and quantization style (eq A-4)
        if qStyle == 0:
            lqcdExpected = 4 + 3 * levels
        elif qStyle == 2:
            lqcdExpected = 5 + 6 * levels
        else:
            lqcdExpected = 5

There are several problems here:

  1. levels is calculated from rewritten form of Eq A-4, but then that same equation is used to do the lqcdConsistencyCheck (the outcome of which is totally meaningless as a result).

  2. levels is now undefined if qStyle is 1 UPDATE: not a problem because in this case mu and epsilon can be determined by reading a fixed-length chunk of 2 bytes

  3. According to the standard, "number_decomposition_levels is defined in the COD and COC marker segments", so we must really use those numbers. BUT in that case things get a bit complicated because we must take into account the precedence order of the main header and tile part header level COD and COC markers! So for a main header-level we would need to check for (in order of increasing precedence):

    1. COD, main header;
    2. COC, main header.

    And for a tile-part level QCD/QCC:

    1. COD, main header;
    2. COC, main header;
    3. COD, tile-part header of first tile part of this tile;
    4. COC, tile-part header of first tile part of this tile.

    Which gets a bit complicated.

First step would be to pass levels to the validate_qcd/validate_qcc functions as an argument. Value must be establishes outside those functions.

To get around this complexity, another option is to use the rewritten equations to calculate levels (as is done now), and remove lqcdConsistencyCheck/lqccConsistencyCheck.

bitsgalore commented 4 years ago

Went the easy route and did this (also fixes previously erroneous calculation of levels in the qcc validation function):

https://github.com/openpreserve/jpylyzer/commit/85d9221f78399cead22030789e0d26ef82e3734e

Note that there is NO cross-check with info from any of the COD/COC markers. Created a separate issue for this here https://github.com/openpreserve/jpylyzer/issues/134