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. } }
private static void BackwardReferencesHashChainDistanceOnly( int xSize, int ySize, MemoryAllocator memoryAllocator, ReadOnlySpan <uint> bgra, int cacheBits, Vp8LHashChain hashChain, Vp8LBackwardRefs refs, IMemoryOwner <ushort> distArrayBuffer) { int pixCount = xSize * ySize; bool useColorCache = cacheBits > 0; int literalArraySize = WebpConstants.NumLiteralCodes + WebpConstants.NumLengthCodes + (cacheBits > 0 ? 1 << cacheBits : 0); var costModel = new CostModel(literalArraySize); int offsetPrev = -1; int lenPrev = -1; double offsetCost = -1; int firstOffsetIsConstant = -1; // initialized with 'impossible' value. int reach = 0; var colorCache = new ColorCache(); if (useColorCache) { colorCache.Init(cacheBits); } costModel.Build(xSize, cacheBits, refs); using var costManager = new CostManager(memoryAllocator, distArrayBuffer, pixCount, costModel); Span <float> costManagerCosts = costManager.Costs.GetSpan(); Span <ushort> distArray = distArrayBuffer.GetSpan(); // We loop one pixel at a time, but store all currently best points to non-processed locations from this point. distArray[0] = 0; // Add first pixel as literal. AddSingleLiteralWithCostModel(bgra, colorCache, costModel, 0, useColorCache, 0.0f, costManagerCosts, distArray); for (int i = 1; i < pixCount; i++) { float prevCost = costManagerCosts[i - 1]; int offset = hashChain.FindOffset(i); int len = hashChain.FindLength(i); // Try adding the pixel as a literal. AddSingleLiteralWithCostModel(bgra, colorCache, costModel, i, useColorCache, prevCost, costManagerCosts, distArray); // If we are dealing with a non-literal. if (len >= 2) { if (offset != offsetPrev) { int code = DistanceToPlaneCode(xSize, offset); offsetCost = costModel.GetDistanceCost(code); firstOffsetIsConstant = 1; costManager.PushInterval(prevCost + offsetCost, i, len); } else { // Instead of considering all contributions from a pixel i by calling: // costManager.PushInterval(prevCost + offsetCost, i, len); // we optimize these contributions in case offsetCost stays the same // for consecutive pixels. This describes a set of pixels similar to a // previous set (e.g. constant color regions). if (firstOffsetIsConstant != 0) { reach = i - 1 + lenPrev - 1; firstOffsetIsConstant = 0; } if (i + len - 1 > reach) { int lenJ = 0; int j; for (j = i; j <= reach; j++) { int offsetJ = hashChain.FindOffset(j + 1); lenJ = hashChain.FindLength(j + 1); if (offsetJ != offset) { lenJ = hashChain.FindLength(j); break; } } // Update the cost at j - 1 and j. costManager.UpdateCostAtIndex(j - 1, false); costManager.UpdateCostAtIndex(j, false); costManager.PushInterval(costManagerCosts[j - 1] + offsetCost, j, lenJ); reach = j + lenJ - 1; } } } costManager.UpdateCostAtIndex(i, true); offsetPrev = offset; lenPrev = len; } }