private static void BackwardReferencesHashChainFollowChosenPath(ReadOnlySpan <uint> bgra, int cacheBits, Span <ushort> chosenPath, int chosenPathSize, Vp8LHashChain hashChain, Vp8LBackwardRefs backwardRefs) { bool useColorCache = cacheBits > 0; var colorCache = new ColorCache(); int i = 0; if (useColorCache) { colorCache.Init(cacheBits); } backwardRefs.Refs.Clear(); for (int ix = 0; ix < chosenPathSize; ix++) { int len = chosenPath[ix]; if (len != 1) { int offset = hashChain.FindOffset(i); backwardRefs.Add(PixOrCopy.CreateCopy((uint)offset, (ushort)len)); if (useColorCache) { for (int k = 0; k < len; k++) { colorCache.Insert(bgra[i + k]); } } i += len; } else { PixOrCopy v; int idx = useColorCache ? colorCache.Contains(bgra[i]) : -1; if (idx >= 0) { // useColorCache is true and color cache contains bgra[i] // Push pixel as a color cache index. v = PixOrCopy.CreateCacheIdx(idx); } else { if (useColorCache) { colorCache.Insert(bgra[i]); } v = PixOrCopy.CreateLiteral(bgra[i]); } backwardRefs.Add(v); i++; } } }
/// <summary> /// Update (in-place) backward references for the specified cacheBits. /// </summary> private static void BackwardRefsWithLocalCache(ReadOnlySpan <uint> bgra, int cacheBits, Vp8LBackwardRefs refs) { int pixelIndex = 0; var colorCache = new ColorCache(); colorCache.Init(cacheBits); for (int idx = 0; idx < refs.Refs.Count; idx++) { PixOrCopy v = refs.Refs[idx]; if (v.IsLiteral()) { uint bgraLiteral = v.BgraOrDistance; int ix = colorCache.Contains(bgraLiteral); if (ix >= 0) { // Color cache contains bgraLiteral v.Mode = PixOrCopyMode.CacheIdx; v.BgraOrDistance = (uint)ix; v.Len = 1; } else { colorCache.Insert(bgraLiteral); } pixelIndex++; } else { // refs was created without local cache, so it can not have cache indexes. for (int k = 0; k < v.Len; ++k) { colorCache.Insert(bgra[pixelIndex++]); } } } }
private static void AddSingleLiteralWithCostModel( ReadOnlySpan <uint> bgra, ColorCache colorCache, CostModel costModel, int idx, bool useColorCache, float prevCost, Span <float> cost, Span <ushort> distArray) { double costVal = prevCost; uint color = bgra[idx]; int ix = useColorCache ? colorCache.Contains(color) : -1; if (ix >= 0) { double mul0 = 0.68; costVal += costModel.GetCacheCost((uint)ix) * mul0; } else { double mul1 = 0.82; if (useColorCache) { colorCache.Insert(color); } costVal += costModel.GetLiteralCost(color) * mul1; } if (cost[idx] > costVal) { cost[idx] = (float)costVal; distArray[idx] = 1; // only one is inserted. } }