﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
1472	Diff between specification and HM on palette coding	forayr		"In the last specification, palette_coding() is specified as below:
{{{
palette_coding( x0, y0, nCbS ) {
  ...
  PaletteRun = nCbS * nCbS − PaletteScanPos − 1
  ...
  if( MaxPaletteIndex > 0 ) {
    if ( CopyAboveIndicesFlag[ xC ][ yC ] == 0 )
       remainingNumIndices − = 1
    PaletteMaxRun = nCbS * nCbS − PaletteScanPos − 1 − remainingNumIndices − copy_above_indices_for_final_run_flag
    if( remainingNumIndices > 0 || CopyAboveIndicesFlag[ xC ][ yC ] != copy_above_indices_for_final_run_flag )
      if( PaletteMaxRun > 0 ) {
        palette_run_prefix
        if( ( palette_run_prefix > 1 ) && ( PaletteMaxRun != ( 1 << ( palette_run_prefix − 1 ) ) ) )
          palette_run_suffix
      }
  }
  ...
}
}}}
When PaletteMaxRun is equal to 0, no palette_run_prefix is parsed. There is no inference rule for this syntax element.
In this case, PaletteRun is not derived from palette_run_prefix and palette_run_suffix.

It is set to default value: nCbS * nCbS − PaletteScanPos − 1; as specified above in the parsing.
However, it seems that PaletteRun should be set to 0 according to the semantic of PaletteMaxRun
(7.4.9.13 Palette semantics: ""The variable PaletteMaxRun represents the maximum possible value for PaletteRun"").
In the HM, PaletteRun is set to 0 in this case.

What is the right value for PaletteRun when PaletteMaxRun is equal to 0:
  - nCbS * nCbS − PaletteScanPos − 1
or
  - 0 ?


In the same idea, the variable PaletteMaxRun is derived before checking the following condition:
{{{
 remainingNumIndices > 0 || CopyAboveIndicesFlag[ xC ][ yC ] != copy_above_indices_for_final_run_flag
}}}

However, when this condition is not verified, the variable PaletteMaxRun is not used and could violate the condition:
(7.4.9.13)  ""It is a requirement of bitstream conformance that the value of PaletteMaxRun shall be greater than or equal to 0.""

Indeed, it is possible to have PaletteMaxRun equal to -1 when these 3 conditions are filled:
    - PaletteScanPos = (nCbs * nCbs) - 1
    - remainingNumIndices = 0
    - copy_above_indices_for_final_run_flag = 1
This case appears especially in HM generated streams.

Is this case a legitimate one ?
If, as I believe, it is, this constraint needs to be verified after the condition.
The easiest way to do this is to move PaletteMaxRun derivation after the condition, as following:

{{{
 palette_coding( x0, y0, nCbS ) {
   ...
   PaletteRun = nCbS * nCbS − PaletteScanPos − 1
   ...
   if( MaxPaletteIndex > 0 ) {
     if ( CopyAboveIndicesFlag[ xC ][ yC ] == 0 )
       remainingNumIndices − = 1
       if( remainingNumIndices > 0 || CopyAboveIndicesFlag[ xC ][ yC ] != copy_above_indices_for_final_run_flag ) {     
         PaletteMaxRun = nCbS * nCbS − PaletteScanPos − 1 − remainingNumIndices − copy_above_indices_for_final_run_flag
         if( PaletteMaxRun > 0 ) {
           palette_run_prefix
           if( ( palette_run_prefix > 1 ) && ( PaletteMaxRun != ( 1 << ( palette_run_prefix − 1 ) ) ) )
             palette_run_suffix
         }
      }
   }
   ...
 }
}}}"	defect	new	major		HM SCC				jct-vc@…
