/// <summary> /// Get the symbol entropy for the distribution 'population'. /// </summary> private static double PopulationCost(uint[] population, int length, ref uint trivialSym, ref bool isUsed, Vp8LStreaks stats, Vp8LBitEntropy bitEntropy) { bitEntropy.Init(); stats.Clear(); bitEntropy.BitsEntropyUnrefined(population, length, stats); trivialSym = (bitEntropy.NoneZeros == 1) ? bitEntropy.NoneZeroCode : NonTrivialSym; // The histogram is used if there is at least one non-zero streak. isUsed = stats.Streaks[1][0] != 0 || stats.Streaks[1][1] != 0; return(bitEntropy.BitsEntropyRefine() + stats.FinalHuffmanCost()); }
private static double GetCombinedEntropy(uint[] x, uint[] y, int length, bool isXUsed, bool isYUsed, bool trivialAtEnd, Vp8LStreaks stats, Vp8LBitEntropy bitEntropy) { stats.Clear(); bitEntropy.Init(); if (trivialAtEnd) { // This configuration is due to palettization that transforms an indexed // pixel into 0xff000000 | (pixel << 8) in BundleColorMap. // BitsEntropyRefine is 0 for histograms with only one non-zero value. // Only FinalHuffmanCost needs to be evaluated. // Deal with the non-zero value at index 0 or length-1. stats.Streaks[1][0] = 1; // Deal with the following/previous zero streak. stats.Counts[0] = 1; stats.Streaks[0][1] = length - 1; return(stats.FinalHuffmanCost()); } if (isXUsed) { if (isYUsed) { bitEntropy.GetCombinedEntropyUnrefined(x, y, length, stats); } else { bitEntropy.GetEntropyUnrefined(x, length, stats); } } else { if (isYUsed) { bitEntropy.GetEntropyUnrefined(y, length, stats); } else { stats.Counts[0] = 1; stats.Streaks[0][length > 3 ? 1 : 0] = length; bitEntropy.Init(); } } return(bitEntropy.BitsEntropyRefine() + stats.FinalHuffmanCost()); }